我有一个注入界面我是单元测试。有问题的方法是有效的,但我正在尝试编写一个单元测试,确认返回的样本数据是完整和准确的。我的测试对我来说是正确的,甚至结果看起来都相同,但测试失败,“CollectionAssert.AreEquivalent失败。预期集合包含1次出现。实际集合包含0次出现。”
[TestMethod]
public void Should_Get_All_Amenities()
{
var amenitiesRep = _ninjectKernel.Get<IAmenityRepository>();
var amenities = amenitiesRep.GetAmenities();
var expected = new List<Amenity>
{
new Amenity() {Id = 1, Name = "Pool", Category = "resort"},
new Amenity() {Id = 2, Name = "Hottub", Category = "resort"},
new Amenity() {Id = 3, Name = "Steamroom", Category = "unit"}
};
Assert.IsNotNull(amenities);
Assert.IsTrue(amenities.Count() == 3);
CollectionAssert.AreEquivalent(expected, amenities);
}
(来自我的TestRepository的相关代码)
var amenities = new List<Amenity>
{
new Amenity() {Id = 1, Name = "Pool", Category = "resort"},
new Amenity() {Id = 2, Name = "Hottub", Category = "resort"},
new Amenity() {Id = 3, Name = "Steamroom", Category = "unit"}
};
var mockAmenitiesRep = new Mock<IAmenityRepository>();
mockAmenitiesRep.Setup(_m => _m.GetAmenities()).Returns(amenities);
Kernel.Bind<IAmenityRepository>().ToConstant(mockAmenitiesRep.Object);
我可以确认所有数据都在CollectionAssert中正确填充,每个字段看起来都匹配1对1,相同数量的对象,相同的对象类型,所以我只是丢失了为什么测试失败。
(编辑:代码失败的行是CollectionAssert)
答案 0 :(得分:9)
这是因为Amenity是一个引用类型,因此CollectionAssert.AreEquivalent通过引用的地址检查相等性。由于预期集合中的项目与GetAmenities()方法中的对象不同,因此返回false。您必须在Amenity类中覆盖相等比较器。
public override bool Equals(object obj)
{
var other = obj as Amenity;
if(other == null)
{
return false;
}
return Id = other.Id && Name == other.Name && Category == other.Category;
}
public override int GetHashCode()
{
return Id.GetHashCode(); //assumes Id is immutable
}
<强>更新强>
请记住,这种方法并不是很好,因为它会导致Equality Pollution。 Alexander Stepaniuk在评论中发布了一个更好的选择。