【问题标题】:Mocking DbSet<T> with RhinoMocks and EF6使用 RhinoMocks 和 EF6 模拟 DbSet<T>
【发布时间】:2014-08-11 13:55:05
【问题描述】:

我在运行测试时收到此错误:System.NotImplementedException : The member 'IQueryable.Provider' has not been implemented on type 'DbSet' ...' 我在创建 fakeDbSet 时看到了 this blog post,但那是在 EF6 之前。有没有更好的方法来使用 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);
}

【问题讨论】:

  • 无论 EF 版本如何,该链接的原理都保持不变。使用暴露IDbSet&lt;&gt; 属性的IMyContext 接口并将其模拟为FakeDbSet&lt;&gt;
  • @AlexG 所以我需要创建 Get IQueryably 表达式的实现,并让 mock 处理非查询相关的方法?

标签: unit-testing dbset


【解决方案1】:

虽然 DBSet 实现了 IQueryable、IDbSet...mock 引擎生成的对象并没有实现它们。

一个可能的解决方案是使用一个 Mocking 框架,该框架支持构建实现许多接口的模拟,如另一个线程中指出的接口(替代): Mocking DBSet, EF Model First

这里有一个实用函数来构建一个模拟 DBSet,其数据存储在一个通用列表中:

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

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 2017-08-24
    • 1970-01-01
    • 2019-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-31
    • 2021-04-07
    • 1970-01-01
    相关资源
    最近更新 更多