如何根据 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 上覆盖 Equals
和 GetHashCode
,然后使用 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。
为什么这有效...
- 你的套牌共有 52 张牌
- 您也在测试(我假设)每副牌包含正确的 52 张牌。
- NUnit 集合的相等性定义为每对元素,按顺序排列,相等。
对于一整套测试,我可能想确保牌组大小没有改变,并且所有元素都是独一无二的。像...
Assert.That(shuffled, Is.EqualTo(DECK_SIZE);
Assert.That(shuffled, Is.Unique);
Assert.That(shuffled, Is.Not.EqualTo(unshuffled));
我是单元测试的新手,我 运行 遇到了一个问题。我有两个 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 上覆盖 Equals
和 GetHashCode
,然后使用 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。
为什么这有效...
- 你的套牌共有 52 张牌
- 您也在测试(我假设)每副牌包含正确的 52 张牌。
- NUnit 集合的相等性定义为每对元素,按顺序排列,相等。
对于一整套测试,我可能想确保牌组大小没有改变,并且所有元素都是独一无二的。像...
Assert.That(shuffled, Is.EqualTo(DECK_SIZE);
Assert.That(shuffled, Is.Unique);
Assert.That(shuffled, Is.Not.EqualTo(unshuffled));