I am getting this error when I run my test: System.NotImplementedException : The member 'IQueryable.Provider' has not been implemented on type 'DbSet' ...' I saw this blog post on creating a fakeDbSet but that was before EF6. Is there a better way to handle this with EF 6?
[Test]
public void Edit_ShouldCall_DbContext_Entry()
{
//arrange
var request = Builder<EditGroupRequest>.CreateNew().Build();
fakeDbSet.Stub(x => x.FirstOrDefault(y => y.ReportGroupNameKey == request.Key)).Return(new MyObject());
//act
_sut.Edit(request);
//assert
_contextFake.AssertWasCalled(x => x.Entry(Arg<MyObject>.Is.Anything).Property(y => y.ReportGroupName).CurrentValue = request.Name);
}
Although DBSet implements IQueryable, IDbSet... the object generated by the mock engine is not implementing them.
A possible solution is using a Mocking framework that supports building mocks that implement many interfaces like the one pointed out in another thread (Substitute): Mocking DBSet, EF Model First
Here you have an utility function to build a mocked DBSet which data is stored on a generic list:
public static DbSet<T> BuildMockedDbSet<T>(List<T> data) where T : class
{
IQueryable<T> queryable = data.AsQueryable();
DbSet<T> fakeDbSet = Substitute.For<DbSet<T>, IQueryable<T>>();
((IQueryable<T>)fakeDbSet).Provider.Returns(queryable.Provider);
((IQueryable<T>)fakeDbSet).Expression.Returns(queryable.Expression);
((IQueryable<T>)fakeDbSet).ElementType.Returns(queryable.ElementType);
((IQueryable<T>)fakeDbSet).GetEnumerator().Returns(queryable.GetEnumerator());
fakeDbSet.AsNoTracking().Returns(fakeDbSet);
return fakeDbSet;
}
Hope it helps.