9

ユニットテストのスキルを向上させるために、小さな練習プロジェクトを行っています。私は最初にEntityFrameworkコードを使用しています。

私はFakeDBSetを使用しています。これは、エンティティの単純なリストに適しています。エンティティツリーが返されるとき、物事はそれほど良くありません。特に、これはEntity Frameworkの魔法の一部であるため、双方向の関係は維持されません。

私には2つのクラスがあります:

public class Book
{
    public virtual ICollection<Review> Reviews {get; set;}
}

public class Review
{
    public virtual Book Book { get; set;}
}

書籍をレビュー用に設定した場合、そのレビューは書籍のレビューコレクションに追加されません。EFを使用している場合は機能しますが、私の偽のバージョンでは機能しません。

この動作を模倣する方法はありますか、それとも双方向の関係を実装するためにEFに依存すべきではありませんか?それとも、データコンテキストをあざけるのは時間の無駄ですか?

4

2 に答える 2

6

これは実際にはかなり一般的な問題です(そして本当に良い答えがない問題です)。変更の検出ループ(追加/削除およびその他のいくつかの変更でトリガーされるプロセス)内で実行されるフィックスアップと呼ばれるEF内で発生するプロセスがあります。これにより、モデルの被リンクが評価されます。コンテキストのモックを開始すると、変更の検出ループが失われ、修正が失われます。

過去に、私はモックのこの特定の制限を理解し、コードで意味をなすように正しい方法でセットアップコードを実行することでこれを回避しました(これはかなり理想的ではありません)。ここでの他のオプションは、単体テストで実際の軽量データベースの形式に移動し、EFを使い続けることです。

于 2012-12-17T19:44:29.310 に答える
5

私が見つけた可能な解決策は、EF修正コードを模倣するモックオブジェクトを作成することです。

モックフレームワークNSubstituteを使用した例を次に示します。

private static Book CreateMockBook()
{
    var book = Substitute.For<Book>();

    // Mock EF fixup: Add a review to collection should also set book for the review
    book.Reviews.Add(Arg.Do<Review>((x) => { if(x.Book != book) x.Book = book; }));

    return book;
}

private static Review CreateMockReview()
{
    var review = Substitute.For<Review>();

    // Mock EF fixup: Set a book for the review should also should add the review to book's review collection
    review.When(x  => x.Book = Arg.Any<Book>()).Do(x => review.Book.Review.Add(review));

    return review;
}

これは非常にうまく機能しますが、この動作をモックする必要があるのは、テストが複雑になりすぎているのか、コードがすべきでない副作用を利用しているのかはわかりません。

他の人がこれをどう思うか興味がありますか?

于 2012-12-21T13:26:49.853 に答える