CollectionAssert.AreEquivalent失败......无法弄清楚原因

Rua*_*rge 2 c# testing unit-testing mocking

我有一个注入接口我是单元测试.有问题的方法是有效的,但我正在尝试编写一个单元测试,确认返回的样本数据是完整和准确的.我的测试对我来说是正确的,甚至结果看起来都相同,但测试失败,"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);
    }
Run Code Online (Sandbox Code Playgroud)

(来自我的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);
Run Code Online (Sandbox Code Playgroud)

我可以确认在CollectionAssert上正确填充了数据,每个字段看起来都匹配1对1,相同数量的对象,相同的对象类型,所以我只是丢失了测试失败的原因.

(编辑:代码失败的行是CollectionAssert)

Ufu*_*arı 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
}
Run Code Online (Sandbox Code Playgroud)

更新:

请记住,这种方法并不是很好,因为它会导致平等污染.Alexander Stepaniuk在评论中发布了更好的选择.

  • 您还可以使用用户定义的项比较器来声明集合的等效性.因此,您不需要为测试目的实现`Equals`.见[here](http://nunit.org/index.php?p=collectionConstraints&r=2.5.10).可以使用`Is.Equivalent`和`Using`修饰符. (2认同)