.net NUnit Assert.AreNotEqual在处理IEnumerable时的错误行为<;T>;?
使用NUnit 2.5.9,以下测试意外失败:.net NUnit Assert.AreNotEqual在处理IEnumerable时的错误行为<;T>;?,.net,nunit,ienumerable,.net,Nunit,Ienumerable,使用NUnit 2.5.9,以下测试意外失败: [TestFixture] public class FooTest { [Test] public void Inequality() { var first = new Foo(new[] { 1 }, 2); var second = new Foo(new[] { 1 }, 3); Assert.AreNotEqual(first, second); } }
[TestFixture]
public class FooTest
{
[Test]
public void Inequality()
{
var first = new Foo(new[] { 1 }, 2);
var second = new Foo(new[] { 1 }, 3);
Assert.AreNotEqual(first, second);
}
}
public struct Foo : IEnumerable<int>, IEquatable<Foo>
{
private readonly IEnumerable<int> values;
public int Bar { get; private set; }
public Foo(IEnumerable<int> values, int bar)
: this()
{
this.values = values;
Bar = bar;
}
public IEnumerator<int> GetEnumerator()
{
return values.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public bool Equals(Foo other)
{
return other.values.SequenceEqual(values) && other.Bar == Bar;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
if (obj.GetType() != typeof(Foo))
{
return false;
}
return Equals((Foo)obj);
}
public override int GetHashCode()
{
unchecked
{
return ((values != null ? values.GetHashCode() : 0) * 397) ^ Bar;
}
}
public static bool operator ==(Foo left, Foo right)
{
return left.Equals(right);
}
public static bool operator !=(Foo left, Foo right)
{
return !left.Equals(right);
}
}
[TestFixture]
公务舱
{
[测试]
公共不平等()
{
var first=newfoo(new[]{1},2);
var second=newfoo(new[]{1},3);
Assert.AreNotEqual(第一,第二);
}
}
公共结构Foo:IEnumerable,IEquatable
{
私有只读IEnumerable值;
公共整型条{get;private set;}
公共Foo(IEnumerable值,int-bar)
:此()
{
这个值=值;
巴=巴;
}
公共IEnumerator GetEnumerator()
{
返回值。GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
返回GetEnumerator();
}
公共布尔等于(Foo其他)
{
返回其他.values.SequenceEqual(值)和&other.Bar==Bar;
}
公共覆盖布尔等于(对象对象对象)
{
if(ReferenceEquals(null,obj))
{
返回false;
}
if(obj.GetType()!=typeof(Foo))
{
返回false;
}
返回等于((Foo)obj);
}
公共覆盖int GetHashCode()
{
未经检查
{
返回((value!=null?values.GetHashCode():0)*397)^Bar;
}
}
公共静态布尔运算符==(左Foo,右Foo)
{
返回左。等于(右);
}
公共静态布尔运算符!=(左Foo,右Foo)
{
返回!左。等于(右);
}
}
深入研究NUnit代码后发现,当NUnit遇到两个实现IEnumerable的对象时,它只是比较这两个集合,并忽略对象上的任何其他属性
我觉得这是不对的:一个对象实现了一个特定的接口这一事实并不限制它只执行那个角色。或者.NET中的IEnumerable接口是一个特例?或者我只是误解了NUnit?看起来这是NUnit中的一个bug,据我所知,它将在3.0版本中修复。下面是一些关于实施
IComparer
的可能工作的讨论:
- NUNit bug追踪器:
Assert.IsTrue(first!=second)
来解决这个问题being@Akash但是,这也不能检查PREPIERT,也要检查<代码> FiST.Bar!第二条.条形码@sll:为什么不呢?OP的类有一个=调用Equals
的code>实现,然后检查条
属性以及集合的元素。