从我经常阅读的实体框架中读取/写入上下文时,建议尽可能缩短上下文的生命周期(每个工作单元一个上下文)。这样做很有意义,但是我应该如何为在每个方法中创建和处理此上下文的类编写单元测试?
让我们看一个简化的虚构示例代码片段:
public class Resource : IResource {
public Item GetItem(string name) {
using(var context = new DbContext()) {
return context.Items.FirstOrDefault(item => item.Name == name);
}
}
}
如果我想对资源进行单元测试,我想模拟 DbContext,所以它会为我返回一些假数据。
我通常的方法是使 DbContext 成为我的类的属性并像这样从外部注入它:
public class Resource : IResource {
public DbContext Context { private get; set; }
public Item GetItem(string name) {
return this.Context.Items.FirstOrDefault(item => item.Name == name);
}
}
这样,注入上下文的实例化类负责生命周期,我可以省略使用,当然我可以注入一个模拟上下文。
现在考虑到,提供一个长期存在的上下文可能是一个坏主意,并且遵循每个工作单元一个上下文的原则,这个选项是不利的。
那么我有什么选择呢?一个想法是注入一个 ContextFactory,它可以像这样按需创建和处理上下文:
public class Resource : IResource {
public DbContextFactory ContextFactory { private get; set; }
public Item GetItem(string name) {
using(var context = ContextFactory.CreateContext()) {
return context.Items.FirstOrDefault(item => item.Name == name);
}
}
}
这是有道理的还是我会进入一个完全错误的方向?