答案 0 :(得分:0)
在我看来,不是通过存储库模式删除对EF的依赖,而是试图模拟EF的特定行为。我无法看到尝试这样做的重点,这将非常困难,EF并不意味着被嘲笑。
您的存储库可能是这样的:
public interface IRepository
{
IEnumerable<EmployeeProfiles> EmployeeProfiles { get; }
}
public class Repository
{
public IEnumerable<EmployeeProfiles> EmployeeProfiles
{
get
{
// Get all the entities including children
using (MyContext context = new MyContext())
{
return context.EmployeeProfiles.Include("EmployeeProperties").ToList();
}
}
}
}
通过这种方式,您已删除了有关如何返回EmployeeProfiles的存储库依赖项。现在你可以嘲笑你的内心(还没有使用过Moles),但是对于Moq,你会做类似的事情:
public void TestEmptyList()
{
var mock = new Mock<IRepository>();
var expected = new List<EmployeeProfiles>();
mock.SetupGet(ep => ep.EmployeeProfiles).Returns(expected);
var actual = mock.Object.EmployeeProfiles;
Assert.AreEqual(expected, actual);
}
因此,如果您将要从数据库中抽象出来的方法/属性放入存储库接口,那么您可以模拟出您可能要返回的任何值。
也许你这样做,我不确定。我不明白你为什么要对EF进行单元测试,你希望获得什么?这将是非常困难的,它不是被设计为嘲笑(非常少的接口/虚拟)。你返回的任何数据的嘲笑,实际上你真正感兴趣的都是如上所述。
答案 1 :(得分:0)
这是完全可能的,在我看来,是有效的。是的,您可以使用存储库模式并模拟您的存储库,这通常就足够了。
然而,我见过两个嘲笑EF的论点:
在这一点上,这是一场神圣的战争,但有些论据支持你正在做的事情。
所以,要与Moles一起做这件事,你需要做两件事。首先,更改创建DbContext的模板,以便所有表的返回类型为IDbSet<>
而不是DbSet<>
。
然后,在您的测试项目中,为IDbSet添加一个测试类实现。我发现this one能够很好地运作。
现在,在您的测试中,您可以执行以下操作:
List<EmployeeProfile> testProfiles = /*your test data here*/;
MMyContext.AllInstances.EmployeeProfilesGet = (instance) =>
{
return new InMemoryDbSet<EmployeeProfile>(testProfiles);
};
// Get all the entities including children
using (MyContext context = new MyContext())
{
return context.EmployeeProfiles.Include("EmployeeProperties").ToList();
}
它快速,简单,并且允许您测试代码,直到它让您无法控制。