努力単位テストのためのShim DbContext ctor


質問

私は、代わりに別のコンストラクタの呼び出しを返すvar context = new MyDbContext()を傍受したいと思います。

EFfortの素晴らしい点は、 単体テスト用の簡単なメモリ内データベースをセットアップすることです。

var connection = Effort.DbConnectionFactory.CreateTransient();
var testContext = new MyDbContext(connection);

しかし、そのcontextをリポジトリに注入する必要があります。

var connection = Effort.DbConnectionFactory.CreateTransient();
var testContext = new MyDbContext(connection);

var context = new MyDbContext()傍受して、 testContext返すことはtestContextですか?

var connection = Effort.DbConnectionFactory.CreateTransient();
var testContext = new MyDbContext(connection);

受け入れられた回答

(編集:私はこれが実際に他のctor呼び出しを返すわけではないことに気付きました。

理解した。あなたがそれをする方法を知っていれば十分に簡単です:

        [TestMethod]
        public void Should_have_a_name_like_this()
        {
            // Arrange
            var connection = Effort.DbConnectionFactory.CreateTransient();
            ShimSolrDbContext.Constructor = context => new SolrDbContext(connection);

            // Act


            // Assert

        }

そしていつものように、EFfortはこのコンストラクタをDbContextクラスに必要とします:

        [TestMethod]
        public void Should_have_a_name_like_this()
        {
            // Arrange
            var connection = Effort.DbConnectionFactory.CreateTransient();
            ShimSolrDbContext.Constructor = context => new SolrDbContext(connection);

            // Act


            // Assert

        }

しかし、それはRepoが特別なTransient接続を気楽に知らないことを意味します:

        [TestMethod]
        public void Should_have_a_name_like_this()
        {
            // Arrange
            var connection = Effort.DbConnectionFactory.CreateTransient();
            ShimSolrDbContext.Constructor = context => new SolrDbContext(connection);

            // Act


            // Assert

        }

人気のある回答

可能な選択肢は2つあります。ファクトリを使用するか、Aspect向けのプログラミング(PostSharpなど)

この記事を参照してください: http : //www.progware.org/Blog/post/Interception-and-Interceptors-in-C-(Aspect-oriented-programming).aspx

PostSharp(AOP)の使用

PostSharpは素晴らしいツールであり、可能な限り最もきれいなインターセプトを実現できます(オブジェクト作成やインターフェイスのファクトリを持っていなくても、クラスやオブジェクトの生成はまったく変更されませんが、フリーのライブラリではありません)。実行時にプロキシを作成するのではなく、コンパイル時にコードを挿入するため、メソッドの代行受信を追加するためのシームレスな方法で初期プログラムが変更されます。
.....
この点で優れた点は、コード内で他に何も変更しないため、新しいキーワードを使用してオブジェクトを生成できることです。

DIと工場パターンの使用

私は個人的にファクトリパターンのアプローチを好みますが、クラスに依存関係を注入する必要はありません。

public interface IDbContextFactory<T> where T : DbContext {
    T Create();
}

public class TestDbContextFactory : IDbContextFactory<MyDbContext> {
    public MyDbContext Create() {
        var connection = Effort.DbConnectionFactory.CreateTransient();
        var testContext = new MyDbContext(connection);
        return testContext;
    }
}

public class FooRepository {
    MyDbContext _context;
    public FooRepository(IDbContextFactory<MyDbContext> factory) { 
        _context = factory.Create(); 
    }
}




ライセンスを受けた: CC-BY-SA
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ