我是单元测试的新手,我遇到了一个问题。我有两个存放对象(卡片)的集合(deck),卡片是有ID、值、套装等的对象。
我正在写一个单元测试,看看我的Shuffle()方法是否有效,所以我想测试一个未洗牌的牌组(它创建了52张ID为0-51的牌)和一个洗牌的牌组是否是相同的顺序.显然,牌是唯一的对象,即使它们持有相同的值。因此,根据定义,测试它们是否相同的结果总是假的。我是一个非常非常新的NUnit(两天前刚刚安装),我仍然在这里和那里的语法上挣扎。
理想情况下,我希望有一个断言来检查两个集合的顺序是否相同,顺序是由牌的ID决定的,因为作为对象,它们都是唯一的,因此总是处于不同的顺序中.现在,我可以检查洗牌后的牌是否不再按ID排序,但这将是一个糟糕的单元测试,因为它假设未洗牌的牌总是按ID排序。我也可以检查未洗牌的牌组,但在没有实际比较两个牌组的情况下,这样测试似乎相当不优雅。
我还想用一个断言来检查我的牌组构造函数只创建唯一的ID,但同样,集合中的所有对象总是唯一的,但我不知道检查所有牌组的一个特定属性是否唯一的语法(如果存在的话)。
我一直在疯狂的上网查资料,我一直在用蛮力尝试很多不同语法的东西,但是我现在很茫然。希望你们能帮帮我,先谢谢了!
来判断这些卡片的顺序是否相同,通过使用? Id
属性,您可以简单地将该属性选择到一个叫做 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));
或者,你可以在他们身上做得过多 Equals
和 GetHashCode
在...上 Card
类,然后用 该 进行平等比较。这将有助于其他可能需要的卡片比较。
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);
你可以用 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}));
我也建议你去看看 流利的断言 库,有时在那里做事情不是很明显,但总的来说它有一些非常有用的功能。
对于你的情况,最简单的方法是只使用NUnit的特性。
Assert.That(shuffled, Is.Not.EqualTo(unshuffled);
请注意,这是假设你已经覆盖了卡片对象的Equals。
为什么会这样做...
对于一套完整的测试,我可能要确保牌组的大小没有变化,而且所有元素都是唯一的。就像...
Assert.That(shuffled, Is.EqualTo(DECK_SIZE);
Assert.That(shuffled, Is.Unique);
Assert.That(shuffled, Is.Not.EqualTo(unshuffled));