EF6 DbSet< T>在Moq中返回null [英] EF6 DbSet<T> returns null in Moq
问题描述
我的应用程序中使用DbContext
(EF6)进行了典型的存储库模式设置:
I have a typical Repository Pattern setup in my application with a DbContext
(EF6):
public class MyDbContext : EFContext<MyDbContext> {
public MyDbContext () { }
public virtual DbSet<CartItem> Cart { get; set; }
和一个存储库:
public class GenericEFRepository<TEntity, TContext>
where TEntity : class, new()
where TContext : EFContext<TContext> {
private readonly TContext _context;
public GenericEFRepository(TContext context) {
_context = context;
}
//...
public virtual TEntity Insert(TEntity item) {
return _context.Set<TEntity>().Add(item);
}
我正在用Moq 4.2(通过本教程)对此进行测试,方法是创建一个模拟上下文:
I'm testing this with Moq 4.2 (following this tutorial) by creating a mock context:
// Arrange
var mockSet = new Mock<DbSet<CartItem>>();
var mockContext = new Mock<MyDbContext>();
mockContext.Setup(c => c.Cart).Returns(mockSet.Object);
// Act
var service = new GenericEFRepository<CartItem, MyDbContext>(mockContext.Object);
service.Insert(new CartItem() {
Id = 1,
Date = DateTime.Now,
UserId = 1,
Detail = string.Empty
});
// Assert
mockSet.Verify(s => s.Add(It.IsAny<CartItem>()), Times.Once());
问题是,当我到达此行时:
The problem is that when I reach this line:
return _context.Set<TEntity>().Add(item);
_context.Set<TEntity>()
返回null.经过一番谷歌搜索之后,似乎在EF5中有必要返回IDbSet<T>
以便Moq模拟该集合,但不是使用EF6.是不是这样,还是我想念一些东西?
_context.Set<TEntity>()
returns null. After some googling it seems in EF5 it was necessary to return IDbSet<T>
for Moq to mock the set, but not with EF6. Is this not the case, or am I missing something?
推荐答案
为Set<T>()
方法添加设置:
mockContext.Setup(c => c.Set<CartItem>()).Returns(mockSet.Object);
即使在真实的EFContext
上,属性Cart
和Set<CartItem>()
指向同一对象,上下文的 mock 也不知道,所以您需要告诉它明确返回什么.
Even though on the real EFContext
the property Cart
and Set<CartItem>()
refer to the same object, the mock of the context doesn't know that, so you need to tell it explicitly what to return.
由于它是一个宽松的模拟,因此对尚未设置的方法的调用将返回默认值,在这种情况下为null
.严格的模拟可以很好地帮助发现此错误,但是具有其他人不愿处理的维护成本.
Since it was a loose mock, the call to a method that hasn't been setup returns the default value, which in this case is null
. Strict mocks are nice in helping find this error, but also have maintenance costs that other folks don't want to deal with.
这篇关于EF6 DbSet< T>在Moq中返回null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!