EF6 DbSet<T> returns null in Moq

我只是一个虾纸丫 提交于 2019-12-10 03:24:39

问题


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; }

and a repository:

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);
    }

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>() 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?


回答1:


Add a setup for the Set<T>() method:

mockContext.Setup(c => c.Set<CartItem>()).Returns(mockSet.Object);

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.

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.



来源:https://stackoverflow.com/questions/25569382/ef6-dbsett-returns-null-in-moq

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!