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合法吗? 是的,了解原因