テストの1つで、コレクションに特定のアイテムがあることを確認します。したがって、私はこのコレクションを予想されるコレクションのアイテムと比較したいと思いますアイテムの順序には関係ありません。現在、私のテストコードは次のようになります。
_[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)
ステートメントは削除されません。
よろしくお願いします。
Xunit.netのBrad Wilsonがこれについて教えてくれました Github Issue LINQのOrderBy
演算子を使用し、その後Assert.Equal
2つのコレクションに順序に関係なく等しいアイテムが含まれていることを確認します。もちろん、最初に注文に使用できる対応する項目クラスのプロパティが必要になります(私の場合は実際にはありませんでした)。
個人的に、私はこの問題を、流れるようなスタイルで適用できる多くのアサーションメソッドを提供するライブラリである FluentAssertions を使用して解決しました。もちろん コレクションの検証に使用できるメソッドも多数あります 。
私の質問のコンテキストでは、次のコードのようなものを使用します:
[Fact]
public void Foo()
{
var first = new[] { 1, 2, 3 };
var second = new[] { 3, 2, 1 };
first.Should().BeEquivalentTo(second);
}
BeEquivalentTo
呼び出しがアイテムの順序を無視するため、このテストは合格です。
Shouldly は、FluentAssertionsを使いたくない場合の良い選択肢でもあります。
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
多分別の方法は:
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)));
Microsoft からCollectionAssert.AreEquivalent
を使用できます
CollectionAssert.AreEquivalent(expected, actual);
これは、コードとほとんど同じです。唯一の単純化は、Assert.True(expected.Contains(...))
の代わりにAssert.Contains
を使用することです。
[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 expected)
Assert.Contains(item, actual);
}