Shim DbContext ctor for Effort unit testing

effort entity-framework microsoft-fakes shim unit-testing

我想截取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

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

        }

但這意味著回購是幸福地沒有意識到特殊的瞬態連接:

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

            // Act


            // Assert

        }

熱門答案

您有兩種可能的選擇。使用工廠或通過面向方面的編程(如PostSharp)

參考這篇文章: http//www.progware.org/Blog/post/Interception-and-Interceptors-in-C-(Aspect-oriented-programming).aspx

使用PostSharp(AOP)

PostSharp是一個很棒的工具,可以實現最乾淨的攔截(即使您的工廠沒有用於創建對象和/或接口,也不會對類和對像生成進行任何更改),但它不是免費的庫。它不是在運行時創建代理,而是在編譯時注入代碼,因此以無縫方式更改初始程序以添加方法攔截。
.....
很酷的是,您不會更改代碼中的任何其他內容,因此仍然可以使用new關鍵字生成對象。

使用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 with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因