Search code examples
c#unit-testingentity-framework-corensubstituteef-core-3.0

Mocking DbContext with NSubstitute and Repository is empty or NotImplementedException


I'm trying to mock my DbContext class to do unit tests with NSubstitute but I cannot recover this data from my fake dbcontext through the repository class.

I have a generic class (SubstituteDbContext) to create sobe DbSet's and set them to the respective DbSet property in my DbContext.

I have the code below for each property in DbContext that I want to mock:

var data = DbSetData.MyData();
var dbSet = SubstituteDbContext.DbSet(data);
dbContext.MyObject.Returns(dbSet);

I create a DbSet to every property with the method below:

public static DbSet<T> getDbSet<T>(IEnumerable<T> data = null)
    where T : class
{
    var dbSet = Substitute.For<DbSet<T>, IQueryable<T>>();

    if (data != null)
    {
        var queryable = data.AsQueryable();
        ((IQueryable<T>)dbSet).Provider.Returns(queryable.Provider);
        ((IQueryable<T>)dbSet).Expression.Returns(queryable.Expression);
        ((IQueryable<T>)dbSet).ElementType.Returns(queryable.ElementType);
        ((IQueryable<T>)dbSet).GetEnumerator().Returns(queryable.GetEnumerator());
        ((IQueryable<T>)dbSet).AsNoTracking().Returns(queryable);
    }
    return dbSet;
}

And in my BaseRepository class (my abstract-parent class for every repository) I have some methods like below to get data:

public virtual IEnumerable<T> List(Expression<Func<T, bool>> predicate)
{
    return DbContext.Set<T>()
        .Where(predicate)
        .AsEnumerable();
}

But when my debugger runs the List method of BaseRepository I have two possible results (because I tried some variations of the code above):

1º I've got System.NotImplementedException
2º The result returned is empty (but 

Solution

  • Your SUT invokes DbContext.Set<T>() however you only set up dbContext.MyObject.Returns(dbSet). You'll need to set up the former.