CollectionAssert
はジェネリックでは使用できないようです。これは非常に苛立たしいことです。テストしたいコードはジェネリックを使用しています。どうしようかな? 2つの間で変換する定型文を書きますか?コレクションの同等性を手動で確認しますか?
これは失敗します:
ICollection<IDictionary<string, string>> expected = // ...
IEnumerable<IDictionary<string, string>> actual = // ...
// error 1 and 2 here
CollectionAssert.AreEqual(expected.GetEnumerator().ToList(), actual.ToList());
// error 3 here
Assert.IsTrue(expected.GetEnumerator().SequenceEquals(actual));
コンパイラエラー:
エラー1:
'System.Collections.Generic.IEnumerator>'には 'ToList'の定義が含まれておらず、タイプ 'System.Collections.Generic.IEnumerator>'の最初の引数を受け入れる拡張メソッド 'ToList'が見つかりませんでした
エラー2
'System.Collections.Generic.IEnumerator>'には 'ToList'の定義が含まれておらず、タイプ 'System.Collections.Generic.IEnumerator>'の最初の引数を受け入れる拡張メソッド 'ToList'が見つかりませんでした
エラー3
'System.Collections.Generic.IEnumerator>'には 'SequenceEquals'の定義が含まれておらず、タイプ 'System.Collections.Generic.IEnumerator>'の最初の引数を受け入れる拡張メソッド 'SequenceEquals'が見つかりませんでした
私は何が間違っているのですか?拡張機能を正しく使用していませんか?
更新:わかりました、これは少し良く見えますが、それでも機能しません:
IEnumerable<IDictionary<string, string>> expected = // ...
IEnumerable<IDictionary<string, string>> actual = // ...
CollectionAssert.AreEquivalent(expected.ToList(), actual.ToList()); // fails
CollectionAssert.IsSubsetOf(expected.ToList(), actual.ToList()); // fails
リストを比較したくありません。私はセットメンバーシップの平等だけを気にします。メンバーの順序は重要ではありません。どうすればこれを回避できますか?
あなたcanジェネリックコレクションでCollectionAssert
を使用します。秘訣は、CollectionAssert
メソッドがICollection
で動作することを理解することです。また、ICollection
を実装する汎用コレクションインターフェイスはほとんどありませんが、_List<T>
_は実装しています。
したがって、ToList
拡張メソッドを使用することでこの制限を回避できます:
_IEnumerable<Foo> expected = //...
IEnumerable<Foo> actual = //...
CollectionAssert.AreEqual(expected.ToList(), actual.ToList());
_
そうは言っても、私はまだCollectionAssert
が他の多くの方法で壊れていると考えているので、次のようにLINQ拡張メソッドでAssert.IsTrue(bool)
を使用する傾向があります。
_Assert.IsTrue(expected.SequenceEqual(actual));
_
FWIW、私は現在、これらの拡張メソッドを使用して他の比較を実行しています。
_public static class EnumerableExtension
{
public static bool IsEquivalentTo(this IEnumerable first, IEnumerable second)
{
var secondList = second.Cast<object>().ToList();
foreach (var item in first)
{
var index = secondList.FindIndex(item.Equals);
if (index < 0)
{
return false;
}
secondList.RemoveAt(index);
}
return secondList.Count == 0;
}
public static bool IsSubsetOf(this IEnumerable first, IEnumerable second)
{
var secondList = second.Cast<object>().ToList();
foreach (var item in first)
{
var index = secondList.FindIndex(item.Equals);
if (index < 0)
{
return false;
}
secondList.RemoveAt(index);
}
return true;
}
}
_
セットを使用している場合は、このイディオムを使用してください
HashSet<string> set1 = new HashSet<string>(){"A","B"};
HashSet<string> set2 = new HashSet<string>(){"B","A"};
Assert.IsTrue(set1.SetEquals(set2));
独自の汎用バージョンを簡単に作成し、それをすべてのテストで使用される基本クラスまたはユーティリティクラスに移動できます。 AllやAnyなどのLINQ演算子に基づいてください。