如何根据 objects 属性之一测试 objects 中的两个 collections 的顺序是否不同?

How to test if two collections of objects are in a different order based on one of the objects' properties?

我是单元测试的新手,我 运行 遇到了一个问题。我有两个 collections(套牌)持有 objects(卡片),卡片是 objects,具有 ID、值、花色等。

我正在编写一个单元测试来查看我的 Shuffle() 方法是否有效,所以我想测试未洗牌的牌组(创建 52 张 ID 为 0-51 的牌)和洗牌的牌组是否在同一副牌中订购与否。 显然,这些卡片是独一无二的 objects,即使它们具有相同的值。所以根据定义,测试它们是否相同总是会导致错误。我对 NUnit 非常非常陌生(两天前才安装它),但我仍在为这里那里的语法苦苦挣扎。

理想情况下,我想要一个断言来检查两个 collection 的顺序是否相同,顺序由卡的 ID 确定,因为 objects,它们都是独一无二的,因此总是以不同的顺序排列。 现在,我可以检查洗牌后的牌组是否不再按 ID 排序,但这将是一个糟糕的单元测试,因为它假设未洗牌的牌组始终按 ID 排序。我也可以检查未洗牌的牌组,但在不实际比较两副牌的情况下以这种方式测试它似乎相当不雅。

我还想要一个断言来检查我的牌组构造函数是否仅创建唯一 ID,但是同样,collection 中的所有 objects 始终是唯一的,但我不知道语法(如果它存在)用于检查所有卡片中的一张特定 属性 的唯一性。

我一直在谷歌上疯狂搜索,我一直在通过暴力尝试很多不同的语法,但我现在不知所措。希望大家帮帮我,先谢谢了!

您可以像这样将 SequnceEqual 与 LINQ Select 一起使用:

class Card
{
    public int CardId { get; set; }
}

Assert.IsTrue(new[] { new Card {CardId = 1}, new Card {CardId = 2}}
        .Select(c => c.CardId)
        .SequenceEqual(new[] {1,2}));

我还建议查看 Fluent Assertions 库,有时在那里做事不是很明显,但总的来说它有一些非常有用的功能。

要使用 Id 属性 来确定卡片的顺序是否相同,您可以简单地 select 将 属性 转换为 IEnumerable然后对它们使用 System.Linq 扩展方法 SequenceEqual

// Where 'unshuffled' and 'shuffled' are both 'List<Card>' objects
var areEqual = unshuffled.Select(c => c.Id).SequenceEqual(shuffled.Select(c => c.Id));

或者,您可以在 Card class 上覆盖 EqualsGetHashCode,然后使用 that平等比较。这将有助于可能需要的其他卡片比较:

public class Card : IEquatable<Card>
{
    public int Id { get; set; }

    public bool Equals(Card other)
    {
        return Id == other?.Id;
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as Card);
    }

    public override int GetHashCode()
    {
        return Id;
    }
}

现在我们的对比代码稍微简单一些:

var areEqual = unshuffled.SequenceEqual(shuffled);

仅使用 NUnit 功能的最简单方法是

Assert.That(shuffled, Is.Not.EqualTo(unshuffled);

请注意,这假设您已覆盖卡片对象的 Equals。

为什么这有效...

  1. 你的套牌共有 52 张牌
  2. 您也在测试(我假设)每副牌包含正确的 52 张牌。
  3. NUnit 集合的相等性定义为每对元素,按顺序排列,相等。

对于一整套测试,我可能想确保牌组大小没有改变,并且所有元素都是独一无二的。像...

Assert.That(shuffled, Is.EqualTo(DECK_SIZE);
Assert.That(shuffled, Is.Unique);
Assert.That(shuffled, Is.Not.EqualTo(unshuffled));