6

最初に EntityFramework コードを使用してコードをテストしようとしています。テスト可能にし、分離テストを可能にするために、DbContext実装するインターフェースを作成しました。クラスをテストしているわけではありませんDbContext。EF コードが期待どおりに動作すると仮定します。

ここで、次の方法を検討してください。

public IEnumerable<User> GetOddId()
{
    return context_.Users.Where((u, i) => i % 2 == 1).AsEnumerable();
}

このメソッドは、(インメモリ LINQ プロバイダーを使用するため) 私のモックで合格しFakeDbSetますが、EF/LINQ to SQL ドライバーを使用すると例外で失敗します。

そのままにして、人々がそのようなクエリを書かないように十分に知っていることを望みますか? 分離テストをあきらめて、実際のデータベースでテストしますか?

DataMigrations (おそらく適切なシード) を使用した LocalDb は、実際のデータベースでのテストに役立ちますか?

答えを正当化してください。

TLDR: インメモリ LINQ と SQL LINQ の違いを考慮して、EntityFramework コードをテストする方法は?

ずっと後の編集:それ以来、私が必要としているものを正確に実行する非常に優れたフレームワークを見つけました。Effort を使用した単体テストに関するブログ記事を書きました。また、いくつかの単体テスト機能が約束されている今後の EF6 では、これらすべてが必要ない可能性があることに注意してください。

4

3 に答える 3

8

この目的のために、SQLiteのインメモリデータベースを使用します。これらは、作成、クエリ、および破棄が非常に迅速であり、全体的なテスト速度にほとんど影響を与えません。データベースを作成してデータを挿入するためのテストフレームワークを設定したら、テストをすばやく作成できます。

もちろん、SQLiteは他のほとんどのデータベースよりもはるかに単純なデータベースであるため、複雑なクエリをそのバージョンのSQLに変換できない場合がありますが、90%のケースをテストする場合は、うまく機能します。

これらのテストは統合テストを構成しますか?私はそうは思わない。彼らはまだあなたのコードの1つのユニット、つまりLINQクエリを生成するビットだけをテストしています。テストしているのは、 1)クエリが正しいデータを返すこと(ただし、前述のようにメモリ内のコレクションを使用してこれを確認できます)、および2)クエリをEntityFrameworkによって有効なSQLに変換できることです。後者をテストする唯一の実際の方法は、実際のEntity Frameworkで、ただしスタブされたデータベースを使用してクエリを実行することです

真の単体テストは、コードの出力だけをテストする必要があり(つまり、生成された式ツリーを解析してチェックする)、記述が難しいと主張することもできますが、実際には何も証明されません。たとえば、サブクエリの代わりに内部結合を生成するようにコードを変更した場合、テストを中断しますか?それが異なる結果を返す場合にのみ、私は考えたでしょう。

于 2012-08-30T12:59:14.763 に答える
1

私が働いている場所には、開発/ベータ/本番SQLサーバーがあります。実際のデータベースでテストを実行する前に、ベータテストデータとシードテストデータに対してテストを作成する場合があります(たとえば、特定の選択をテストする前に挿入するなど)。人々はユニットテストと統合テストを区別しますが、少なくともロジックをテストすることができます。これは、単に指を交差させてデータアクセス層で最高のものを期待するよりも優れています。

テストは簡単ですが、いくつかの重要なケースでは実際にはライブシステムを表していないインメモリプロバイダーはどのような利点がありますか?

編集:私たちはEFを使用していません、ところで...

于 2012-08-30T12:51:17.423 に答える
0

TelerikのJustMockのようなモックフレームワークを使用することをお勧めします(または他の多くのフレームワークから選択します)。

これにより、テストコードで何が起こるかを細かく制御できます。(ここで簡単に紹介します。)

実際のデータベースにクエリを実装する代わりに、クエリを「シミュレート」して、事前定義されたオブジェクトのコレクションを返すことができます。

たとえば、メソッドを呼び出す複数の単体テストを作成し、GetOddId()必要なすべてのテストケース(空のリスト、正しいコンテンツ、間違ったコンテンツ、例外のスローなど)をカバーするさまざまな単体テストを定義できます。

ここまたはNuGet経由で無料の「Lite」バージョンもあります。

于 2012-08-30T16:00:05.247 に答える