4

System.Linq.Expressions.Expression をパラメーターとして受け取るメソッドを持つクラスがあると仮定すると、単体テストにどれだけの価値があるでしょうか?

public void IList<T> Find(Expression expression)
{
    return someCollection.Where(expression).ToList();
}

この種のメソッドの単体テストやモック化は、私にとっては気が遠くなるような経験でした.

次のような任意の式を使用して、このメソッドを単体テストするにはどうすればよいですか

List<Animal> = myAnimalRepository.Find(x => x.Species == "Cat");
4

2 に答える 2

6

各 LINQ プロバイダーは実装固有であるため、これを単体テストするのは少し人工的です。テストでさまざまなアプローチを使用する可能性がありますが、実際の実装については何もわかりません。たとえば、LINQ-to-Objects を介してモックされている場合は、次のように使用できます。

List<Animal> = myAnimalRepository.Find(x => CheckSpecies(x, "Cat"));
...
static bool CheckSpecies(Animal animal, string species) {
    return animal.Species == species;
}

それはLINQ-to-Objectsで機能します...ただし、LINQ-to-Objectsでのみ機能します。同様に、UDF の使用 (または SQL ヘルパー メソッドの 1 つ) は LINQ-to-SQL では機能しますが、Entity Framework では機能しません。

このシナリオでは統合テストのみが役立つという結論に達したので、いいえ。ここでは嘲笑あまり役に立ちません。何か役に立つことをしたという温かい幸せな気持ちになりますが、最終的には、アプリに書いたことが機能するかどうかをテストすることはできません。

さらに優れたアプローチである IMO は、リポジトリ インターフェイスを介してそのようなものを公開しないことです。LINQ クエリをデータ層に制限すると、リスクがなくなり、純粋で予測可能なインターフェイスをテスト (/モック) することになります。

これについては、ここで詳しく説明します。

于 2010-04-22T03:54:02.493 に答える
2

なぜだめですか?- SUT のパブリック インターフェイスの一部です。

これも簡単にテストできそうです。絶対に必要でない限り、私は一般的にモックを使用しません。私は次のようにテストを書きます

[Test]
public void Find()
{
  var animalRepository = new AnimalRepository();
  animalRepository.Add( dog ); // create a object to species = dog and other relevant attr
  animalRespository.Add( cat ); // etc. etc..

  var results = animalRepository.Find( a => a.Species == "Cat");

  Assert.That( results.Is.EquivalentTo( new List<Animal> { cat } ) );
}
  1. 配置: SUT をセットアップして、内部 somecollection にいくつかの既知のオブジェクトが含まれるようにします (例: Add(dog);)。追加(猫); 等
  2. Act: 条件付きで Find メソッドを呼び出す
  3. 主張する:Assert.That( results.Is.EquivalentTo(expected_results)

いくつかのクエリ式を試して、Find メソッドがそれを Where 句として使用していることを確認できます。それはそれを行う必要があります。

于 2010-04-22T02:45:04.293 に答える