Ste*_*ins 8 c# unit-testing entity-framework moq entity-framework-6
我在我的应用程序中使用DbContext
(EF6)设置了典型的存储库模式:
public class MyDbContext : EFContext<MyDbContext> {
public MyDbContext () { }
public virtual DbSet<CartItem> Cart { get; set; }
Run Code Online (Sandbox Code Playgroud)
和一个存储库:
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);
}
Run Code Online (Sandbox Code Playgroud)
我正在使用Moq 4.2(遵循本教程)通过创建模拟上下文来测试它:
// 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());
Run Code Online (Sandbox Code Playgroud)
问题是当我到达这一行时:
return _context.Set<TEntity>().Add(item);
Run Code Online (Sandbox Code Playgroud)
_context.Set<TEntity>()
返回null.经过一些谷歌搜索似乎在EF5中,有必要返回IDbSet<T>
Moq来模拟集合,但不是EF6.是不是这样,或者我错过了什么?
Pat*_*irk 16
添加Set<T>()
方法的设置:
mockContext.Setup(c => c.Set<CartItem>()).Returns(mockSet.Object);
Run Code Online (Sandbox Code Playgroud)
即使在真实EFContext
的属性Cart
和Set<CartItem>()
引用相同的对象,上下文的模拟不知道,所以你需要明确告诉它返回什么.
由于它是一个松散的模拟,因此对尚未设置的方法的调用将返回默认值,在本例中为null
.严格的模拟很有助于发现此错误,但也有其他人不想处理的维护成本.