1

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);
}
Robert
  • 4,306
  • 11
  • 45
  • 95
  • 1
    The principles from that link remain the same regardless of EF version. Use an `IMyContext` interface that exposes `IDbSet<>` properties and mock those as `FakeDbSet<>` – Alex Aug 11 '14 at 14:14
  • @AlexG So I will need to create implementations of the Get IQueryably expressions and let the mock handle the non query related methods? – Robert Aug 11 '14 at 14:28

1 Answers1

0

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.

Community
  • 1
  • 1