【发布时间】:2014-10-23 12:44:16
【问题描述】:
我的应用程序中有一个典型的存储库模式设置,带有 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(在 this tutorial 之后)通过创建一个模拟上下文对此进行测试:
// 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());
问题是当我到达这一行时:
return _context.Set<TEntity>().Add(item);
_context.Set<TEntity>() 返回空值。经过一番谷歌搜索后,在 EF5 中似乎有必要返回 IDbSet<T> 以便 Moq 模拟该集合,但在 EF6 中则不需要。是不是这样,还是我错过了什么?
【问题讨论】:
-
我是否错过了您设置
Set<T>()方法以返回mockSet的位置? -
您必须澄清这一点。根据我链接到的教程,与集合的唯一交易是
var mockSet = new Mock<DbSet<CartItem>>();和mockContext.Setup(c => c.Cart).Returns(mockSet.Object);行。 -
没错,但是在教程的服务代码中(快速浏览后)我没有看到他们调用
Set<T>(),而你的却是。为此添加一个设置,我认为它会起作用。 -
看来你是对的!我想我假设因为
Cart和.Set<CartItem>()指的是同一件事,所以设置Cart就足够了。谢谢!
标签: c# entity-framework unit-testing moq entity-framework-6