C# IEnumerable.contains在集合中找不到匹配项,该集合确实存在
我有一个从foo方法返回的C# IEnumerable.contains在集合中找不到匹配项,该集合确实存在,c#,unit-testing,C#,Unit Testing,我有一个从foo方法返回的IEnumerableMyClass包含一个嵌套类,通常如下所示。问题是断言总是返回false MyClass { SomeNestedClass { public decimal decimalField1; public int intField2; } } 我正在编写一个单元测试来测试Foo方法 // Arrange var expectedItem = new MyClass { n
IEnumerable
MyClass
包含一个嵌套类,通常如下所示。问题是断言总是返回false
MyClass
{
SomeNestedClass
{
public decimal decimalField1;
public int intField2;
}
}
我正在编写一个单元测试来测试Foo
方法
// Arrange
var expectedItem = new MyClass
{
new SomeNestedClass
{
decimalField1 = 10M,
intField2 = 20
}
}
// Act
var results = sut.Foo();
// Assert
Assert.IsTrue(results.Contains(expectedItem));
问题是Assert总是false。我们没有足够的信息(sut.Foo();)的实现),但我怀疑您必须重写MyClass类型中的Object.Equals()方法。
如果没有该选项,Contains()函数将仅检查引用的相等性。
Contains
将在尝试查找匹配项时使用类型的默认相等性比较器,这是类等引用类型的引用比较。因为我们知道列表中没有对您刚刚创建的对象的引用,所以这将不起作用
解决此问题的一个简单方法是使用System.Linq
方法Any()
,如果IEnumerable
中的任何项满足指定条件,该方法将返回true
例如:
Assert.IsTrue(results.Any(result =>
result.decimalField1 == expectedItem.decimalField1 &&
result.intField2 == expectedItem.intField2));
一种稍微费力但可重复使用的方法是编写一个
SomeNestedClass
比较器,它可以传递给Contains
方法(我正在使用SomeNestedClass
,尽管在示例中result
被声明为MyClass
,因为这是唯一一个具有可用于比较的字段的类):
可能不会比较同一个对象。可以使用FirstOrDefault(x=>x.decimalField==expectemItem.decimalField&&x.intField2==expectedItem.inteField2)引用相等是默认值。仅仅因为两个对象看起来相同,并不意味着.NET认为它们相等。
public class SomeNestedClassComparer : IEqualityComparer<MyClass.SomeNestedClass>
{
public bool Equals(MyClass.SomeNestedClass x, MyClass.SomeNestedClass y)
{
if (x == null || y == null) return ReferenceEquals(x, y);
return x.decimalField1 == y.decimalField1 && x.intField2 == y.intField2;
}
public int GetHashCode(MyClass.SomeNestedClass obj)
{
return obj.decimalField1.GetHashCode() * 17 +
obj.intField2.GetHashCode();
}
}
Assert.IsTrue(results.Contains(expectedItem, new SomeNestedClassComparer()));