我需要从数据访问层对内部联接方法进行单元测试。
我的 DAL 看起来像这样:
public class MyDAL:IMyDAL
{
private MyContext context;
public MyDAL(MyContext Context)
{
this.context = Context;
}
public IEnumerable <Parent> Read(int childId)
{
var query = from parent in context.Parent
join child in context.Child on parent.Id equals child.Id
where child.Id == childId
select env;
return query.ToList();
}
我想通过模拟 Entity Framework 来对 Read 方法进行单元测试,请点击此链接 http://msdn.microsoft.com/en-us/data/dn314429.aspx .
[TestMethod]
public void ReadMethod()
{
var data = new List<Parent>
{
new Parent { Id = 20 },
}.AsQueryable();
var data2 = new List<Child>
{
new Child { Id = 8 },
}.AsQueryable();
var mockSetPar = new Mock<DbSet<Parent>>();
var mockSetChild = new Mock<DbSet<Child>>();
mockSetPar.As<IQueryable<Parent>>().Setup(m => m.Provider).Returns(data.Provider);
mockSetPar.As<IQueryable<Parent>>().Setup(m => m.Expression).Returns(data.Expression);
mockSetPar.As<IQueryable<Parent>>().Setup(m => m.ElementType).Returns(data.ElementType);
mockSetPar.As<IQueryable<Parent>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
moockSetChild.As<IQueryable<Child>>().Setup(m => m.Provider).Returns(data2.Provider);
mockSetChild.As<IQueryable<Child>>().Setup(m => m.Expression).Returns(data2.Expression);
mockSetChild.As<IQueryable<Child>>().Setup(m => m.ElementType).Returns(data2.ElementType);
mockSetChild.As<IQueryable<Child>>().Setup(m => m.GetEnumerator()).Returns(data2.GetEnumerator());
var customDbContextMock = new Mock<MyContext>();
customDbContextMock.Setup(x => x.Parent).Returns(mockSetPar.Object);
customDbContextMock.Setup(x => x.Child).Returns(mockSetChild.Object);
var myDAL = new MyDAL(customDbContextMock.Object);
var actual = myDAL.Read(8);
Assert.IsNotNull(actual);
实际结果为空,因为 join 方法尚未被模拟,因此它不会返回任何内容。
如何模拟 join 方法以返回值?
谢谢
最佳答案
数据库交互的内存中测试可能会产生误导,因为 LINQ to Entities 功能是 LINQ to Objects 功能的子集,因此您可以编写一个绿色测试,但查询在生产中总是会抛出异常。
这在概念层面上也是错误的。 DAL 是位于两个系统(app 和 db)边界上的代码。它的责任是将它们整合起来。因此,如果您隔离这些集成组件,您的测试就变得毫无意义,因为它模拟了 SUT 的核心职责。
要测试查询逻辑,您必须使用行为类似于生产数据库提供程序的数据库提供程序。所以你需要集成测试。 = 一个有用的解决方案是使用 SQLite 内存数据库。在 Entity Framework 涵盖的大多数场景中,它的行为就像真正的数据库,但在单元测试中的执行速度几乎与基于内存集合的模拟一样快。
如果您愿意,您可以将 SQLite 视为类固醇数据库模拟。
关于entity-framework - 模拟 Entity Framework 内连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22660676/