断言列表中字段的唯一性

我在C#中创建了一个列表,我想进行测试,看看Id字段的所有值是否都是唯一的。

public static List _reviews = new List { new RestaurantReview { Id = 1, Name = "McDonalds", }, new RestaurantReview { Id = 2, Name = "Burger King", }, } 

因为我做了一些调试,我发现它正在通过列表运行,但我没有得到正确的测试值。 有人可以解释我在这里做错了吗?

 [TestMethod()] public void CheckReviewIds() { var FirstReview = ReviewsController._reviews.First(); bool AllUniqueIds = ReviewsController._reviews.All(s => s.Id == FirstReview.Id); Assert.IsFalse(AllUniqueIds); } 

提前致谢。

您正在检查所有值是否与第一个值不相等。 如果值是例如[1, 2, 3, 3 ],则可能是这种情况,没有一个等于第一个但是它本身,但是3 == 3

相反,您可以通过GroupBy按值对它们进行分组,然后检查它们是否不同。 我假设性能在这里不是一个大问题(如果列表少于100000项,我认为是这种情况):

  ReviewsController._reviews.GroupBy(x => x.Id).Count() == ReviewsController._reviews.Count; 

请注意,测试组件的内部状态可能不是最好的主意,而是测试它正在公开的API。 否则,您通过unit testing定义的合同受到实施细节的限制。 最后一段只是关于男人的意见。

另一个在时间方面具有更好性能的解决方案(特别是如果您拥有的数据集很大)是使用这样的HashSet :

 bool IsAllUnique(IEnumerable values) { HashSet hash_set = new HashSet(); return values.All(x => hash_set.Add(x)); } 

然后你可以像这样使用它:

 bool unique = IsAllUnique(ReviewsController._reviews.Select(x => x.Id)); 

此解决方案取决于如果我们尝试添加的值已存在, HashSet.Add将返回false。

此解决方案具有更好性能的一个原因是,如果检测到重复项,则不必遍历列表中的其余项。

我发现validation这一点的最简单方法是计算所有不同的值,并将它们与实际值的数量进行比较:

 var actual = ReviewsController._reviews.Select(r => r.Id).Distinct().Count(); var expected = ReviewsController._reviews.Count(); Assert.Equal(expected, actual);