我们有一个Web API前端和一个业务层,其中包含包含Entity Framework Linq-to-Entities的服务对象。我们正在使用Code-First,但我们没有生成数据库。相反,我们使用EF反向POCO生成器。
我们有两个持续存在的问题,这两个问题都与必须等待我们的DBA完成表格工作有关。第一个问题是我们没有完成表结构来生成POCO,第二个问题是新表或列中没有数据。
是否有一种简单的方法来伪造结构和/或数据,以便我们可以完成Linq到实体的查询?我的第一个想法是将POCO生成为部分并暂时添加属性到非生成的部分类。然后对于假数据,我想知道是否有办法拦截Linq查询并返回假数据,直到数据库更改完成,然后我们删除拦截器。这可能吗?或者有更简单的方法来实现这一目标吗?
答案 0 :(得分:0)
所以你基本上是在询问如何使用模拟实体提供模拟的DbSet。这是可能的,因为它实际上是你能够使用EF6单元测试方法的。
摘要,在我详细介绍之前: *安装Moq nuget包。 *创建一个辅助方法,该方法可以获取实体并返回该实体的模拟DbSet。
private static Mock<DbSet<T>> CreateDbSetMock<T>(IEnumerable<T> elements) where T : class
{
var elementsAsQueryable = elements.AsQueryable();
var dbSetMock = new Mock<DbSet<T>>();
dbSetMock.As<IQueryable<T>>().Setup(m => m.Provider).Returns(elementsAsQueryable.Provider);
dbSetMock.As<IQueryable<T>>().Setup(m => m.Expression).Returns(elementsAsQueryable.Expression);
dbSetMock.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(elementsAsQueryable.ElementType);
dbSetMock.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(elementsAsQueryable.GetEnumerator());
mockSet.Setup(t => t.Add(It.IsAny<T>())).Callback<T>(data.Add);
mockSet.Setup(t => t.Remove(It.IsAny<T>())).Callback<T>(t => data.Remove(t));
return dbSetMock;
}
然后创建新实体并以这种方式创建模拟的DbSet。 var dbSet = CreateDbSetMock(new List());
按照您的预期添加数据。 dbSet.Add(new NewEntity {somedata});
然后像您期望的那样查询数据, dbSet.Where(某些逻辑).FirstOrDefault();
如果您使用的是EF Core,我告诉您只需使用内存提供程序,上述代码仅适用于EF 6。