在我的一个测试中,我想确保集合中有某些项目。因此,我想将此集合与预期集合的项目进行比较,而不是关于项目的顺序。目前,我的测试代码看起来有点像这样:
[Fact]
public void SomeTest()
{
// Do something in Arrange and Act phase to obtain a collection
List<int> actual = ...
// Now the important stuff in the Assert phase
var expected = new List<int> { 42, 87, 30 };
Assert.Equal(expected.Count, actual.Count);
foreach (var item in actual)
Assert.True(expected.Contains(item));
}
在xunit.net中有没有更简单的方法来实现这个目标?我不能使用Assert.Equal
,因为此方法检查两个集合中项目的顺序是否相同。我查看了Assert.Collection
,但这并没有删除上面代码中的Assert.Equal(expected.Count, actual.Count)
语句。
提前感谢您的回答。
答案 0 :(得分:21)
OrderBy
运算符,然后使用Assert.Equal
来验证两个集合包含相同的项而不考虑它们的顺序。当然,您必须在相应的项目类上拥有一个属性,您可以在第一个位置使用它(在我的情况下我没有真正拥有)。
就个人而言,我通过使用FluentAssertions解决了这个问题,there are also a lot of methods that you can use to validate collections是一个提供大量断言方法的库,可以以流畅的方式应用。当然,Shouldly。
在我的问题中,我会使用类似下面的代码:
[Fact]
public void Foo()
{
var first = new[] { 1, 2, 3 };
var second = new[] { 3, 2, 1 };
first.Should().BeEquivalentTo(second);
}
此测试通过,因为BeEquivalentTo
调用忽略了项目的顺序。
http://hpics.li/9fc4863也是一个不错的选择。
答案 1 :(得分:11)
不是Xunit,而是Linq回答:
bool areSame = !expected.Except(actual).Any() && expected.Count == actual.Count;
所以在XUnit中:
Assert.True(!expected.Except(actual).Any() && expected.Count == actual.Count));
正如@ robi-y所说,在Microsoft.VisualStudio.QualityTools.UnitTestFramework
中有CollectionAssert.AreEquivalent
答案 2 :(得分:6)
也许另一种方式是:
Assert.True(expected.SequenceEqual(actual));
这也会检查订单。这就是内部发生的事情:
using (IEnumerator<TSource> e1 = first.GetEnumerator())
using (IEnumerator<TSource> e2 = second.GetEnumerator())
{
while (e1.MoveNext())
{
if (!(e2.MoveNext() && comparer.Equals(e1.Current, e2.Current))) return false;
}
if (e2.MoveNext()) return false;
}
return true;
因此,如果您不关心订单,只需在以下订单中订购:
Assert.True(expected.OrderBy(i => i).SequenceEqual(actual.OrderBy(i => i)));
答案 3 :(得分:1)
You can use CollectionAssert.AreEquivalent
from Microsoft
CollectionAssert.AreEquivalent(expected, actual);
答案 4 :(得分:1)
如果您集合中的项目保证是唯一的,您可以使用 HashSet
。这是因为 HashSet
本质上是无序的。
[Fact]
public void Foo()
{
var expected = new HashSet<int> { 1, 2 ,3 };
var actual = new HashSet<int> { 3, 2, 1 };
Assert.Equal(expected, actual);
}
这是可行的,因为 xUnit 使用 ISet.SetEquals()
方法。
此方法忽略元素的顺序以及其他中的任何重复元素。
如果 actual
集合只是一个常规集合(不是 HashSet
),那么您仍然可以自己使用 SetEquals()
,但您必须意识到重复项将被忽略。
[Fact]
public void Foo()
{
var expected = new HashSet<int> { 1, 2 ,3 };
var actual = new [] { 3, 2, 1, 1, 1 };
// This also passes, but may not be what you want
Assert.True(expected.SetEquals(actual));
}
答案 5 :(得分:0)
这几乎与您的代码相同。唯一的简化是使用from django_seed import Seed
seeder = Seed.seeder()
from myapp.models import Game, Player
seeder.add_entity(Game, 5)
seeder.add_entity(Player, 10)
inserted_pks = seeder.execute()
而不是spark-defaults.conf
。
spark.master.rest.enabled true