私はこれに対する良い解決策を見つけようとしてきましたが、運がなかったので、正しいキーワードを探していないか、最初から間違ったことをしているので、問題は実際には存在しないはずです.
明確化のための更新:これを統合テストとしてではなく単体テストとして機能させたいので、これをデータベースにヒットさせたくありませんが、単体テストで EF が変更を保持するときに行われた関連付けをモックしたいと考えています。
元の質問:
次のようなサービス メソッドをテストしているとします。
[Test]
public void AssignAuthorToBook_NewBookNewAuthor_SuccessfullyAssigned()
{
IBookService service = new BookService();
var book = new Book();
var Author = new Author() { Id = 123 };
service.AssignAuthorToBook(book, author);
Assert.AreEqual(book.AuthorId, 123);
}
AssignAuthorToBook
ここで、コードを使用して実際に機能するため、このテストが失敗したとしましょう。エンティティを割り当てているためですbook.Author = author;
。AuthorId
これがコンテキストで Entity FrameworkSaveChanges()
メソッドを使用して永続化されると、エンティティが関連付けられ、ID が関連付けられます。ただし、上記の例では、Entity Framework のロジックは適用されていません。私が言っているのは、一度SaveChanges()
呼び出されたコードは機能しますが、単体テストは失敗するということです。
この単純な例では、コードの直前にテストを記述したばかりで、簡単に修正できるため、テストが失敗した理由がすぐにわかるでしょう。しかし、より複雑な操作や、エンティティの関連付け方法を変更する可能性のある将来の変更により、テストは中断されるが機能は中断されない可能性がある操作の場合、単体テストはどのように行うのが最善でしょうか?
私の考えは次のとおりです。
- サービス レイヤーは永続レイヤーを認識しないようにする必要があります。単体テストでデータ コンテキストをモックして、それが機能する方法をモックする必要がありますか? 関連付けを自動的に結び付ける簡単な方法はありますか (つまり、エンティティが使用されている場合
Id
は正しいエンティティに割り当てId
、エンティティが使用されている場合は正しいエンティティを割り当てます)。 - それとも、テストを少し異なる方法で構成する必要がありますか?
私が継承した現在のプロジェクトに存在するテストは、上記の例のように機能しますが、アプローチに何か問題があり、おそらく一般的な問題に対する簡単な解決策を見つけることができなかったことが気になります。データ コンテキストはモック化する必要があると思いますが、関連付けを動的に作成するには、モックに多くのコードを追加する必要があるようです。これはすでに解決されていますか?
更新:これらは私がこれまでに見つけた最も近い答えですが、私が求めているものとはまったく異なります. 私はEF自体をテストしたくありません。リポジトリにアクセスするサービスメソッドをテストするためのベストプラクティスは何だろうと思っただけです(直接または同じコンテキストを共有する他のリポジトリを介してナビゲーションプロパティを介して)。
Entity Framework のナビゲーション プロパティ インテリジェンスをモックするにはどうすればよいですか?
モックされたデータ コンテキストと外部キー/ナビゲーション プロパティ
テストするEntity Framework 4.1の偽のDbContext
ADO.NET モッキング コンテキスト ジェネレーターの使用時にナビゲーション プロパティが設定されない
これまでの結論:これは単体テストでは不可能であり、実際の DB との統合テストを使用してのみ可能です。ナビゲーション プロパティを動的に関連付けるコードを作成することはできますが、モック データ コンテキストが実際のコンテキストを完全に複製することはありません。完璧ではないにしても、ナビゲーション プロパティを自動的に関連付けることができるソリューションがあれば幸いです(ユニット テストの成功の性質は、とにかく機能を保証するものではありません)。モッキング コンテキスト ジェネレーターは近づいていますが、実装で部分クラスを使用して機能が追加された場合に備えて、すべてのエンティティのモック バージョンが必要になるようです。