EF6 DbSet <T> returns null in Moq

I have a typical repository template setup in my application with DbContext (EF6):

 public class MyDbContext : EFContext<MyDbContext> { public MyDbContext () { } public virtual DbSet<CartItem> Cart { get; set; } 

and 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 am testing this with Moq 4.2 (following this tutorial ), creating a context layout:

  // 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 searching in EF5, it was necessary to return an IDbSet<T> for Moq in order to mock the set, but not with EF6. Is this not true, or am I missing something?

+8
c # unit-testing moq entity-framework entity-framework-6
source share
1 answer

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

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

Even if the Cart and Set<CartItem>() property refer to the same object on the real EFContext , the context layout does not know this, so you need to explicitly tell it what to return.

Since it was a free layout, calling a method that was not configured returns a default value, which in this case is null . Severe bullying helps to find this error, but also has maintenance costs that other people do not want to deal with .

+15
source share

All Articles