【问题标题】:CollectionAssert.AreEquivalent failing... can't figure out whyCollectionAssert.AreEquivalent 失败...无法弄清楚为什么
【发布时间】:2013-04-04 21:01:42
【问题描述】:

我有一个注入接口,我正在单元测试。有问题的方法有效,但我正在尝试编写一个单元测试来确认返回的样本数据是完整且准确的。我的测试对我来说看起来是正确的,甚至结果看起来都一样,但测试失败并显示“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)

【问题讨论】:

  • 您的 Amenity.Equals 方法是什么样的?
  • 我没有指定 Amenity.Equals 方法。 (我没有看到任何例子,但我也没有找到任何关于实施这种形式的单元测试的真正好的指南,所以它可能是我根本不知道我需要的东西)

标签: c# unit-testing testing mocking


【解决方案1】:

这是因为 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 在 cmets 中发布了一个更好的替代方案。

【讨论】:

  • 谢谢,我会试试这个,让你知道会发生什么。
  • 您还可以使用用户定义的项目比较器来断言集合的等价性。因此,您无需为测试目的实现Equals。见hereIs.EquivalentUsing 修饰符可以用于此。
  • @AlexanderStepaniuk 我认为这是一种更好的方法。我已经更新了我的帖子。
猜你喜欢
  • 2016-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-22
  • 2015-04-06
  • 1970-01-01
相关资源
最近更新 更多