使用RhinoMock测试DbSet

时间:2017-07-06 12:23:37

标签: unit-testing rhino-mocks dbset

我需要用RhinoMock模拟一个DbSet。我找到了一种模拟IDbSet的方法,但不是DbSet。我找到了另一种模拟框架的方法,但我必须使用RhinoMock。有人可以把它翻译成犀牛模拟吗?

我在http://www.loganfranken.com/blog/517/mocking-dbset-queries-in-ef6/上找到了这个:

private static DbSet<T> GetQueryableMockDbSet<T>(params T[] sourceList) where T : class
{
   var queryable = sourceList.AsQueryable();

   var dbSet = new Mock<DbSet<T>>();
   dbSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(queryable.Provider);
   dbSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(queryable.Expression);
   dbSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(queryable.ElementType);
   dbSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(() => queryable.GetEnumerator());

   return dbSet.Object;
}

由于

1 个答案:

答案 0 :(得分:0)

更新

虽然RhinoMocks支持使用相同的模拟模拟多个接口,正如我在初始答案中所使用的那样,它显然不支持显式接口,DbSet用于{{} 1}}。正如@Dosihris在评论中指出的那样,它引发了一个例外

  

由于CLR如何处理显式接口实现,我们无法代理此方法。

这似乎是RhinoMocks中嵌入的Castle.DynamicProxy(v2.1.0.5967)版本的例外,该版本来自2010年之前。较新版本的DynamicProxy支持此功能,因此如果您真的想要冒险,可以使用DynamicProxy的更新版本重新编译RhinoMocks。

或者,您可以尝试直接在测试项目中引用DynamicProxy,并使用绑定重定向强制RhinoMocks使用较新版本。鉴于RhinoMocks中版本的年龄,可能与较新的DynamicProxy API不兼容,因此这可能不会成功。

或者,您可以转移到仍然主动维护的框架,例如Moq或NSubstitute(它们都使用较新版本的DynamicProxy)。

这是使用RhinoMocks的等效逻辑:

IQueryable

根据您是否要验证属性是否已被调用,您可能希望在上述每个内容中使用using Rhino.Mocks; private static DbSet<T> GetQueryableMockDbSet<T>(params T[] sourceList) where T : class { var queryable = sourceList.AsQueryable(); var dbSet = Rhino.Mocks.MockRepository.GenerateMock<DbSet<T>, IQueryable<T>>(); ((IQueryable<T>)dbSet).Expect(m => m.Provider).Return(queryable.Provider); ((IQueryable<T>)dbSet).Expect(m => m.Expression).Return(queryable.Expression); ((IQueryable<T>)dbSet).Expect(m => m.ElementType).Return(queryable.ElementType); ((IQueryable<T>)dbSet).Expect(m => m.GetEnumerator()) .Return(null) // will be ignored but still the API requires it .WhenCalled((methodInvokation) => methodInvokation.ReturnValue = queryable.GetEnumerator()); return dbSet; } 而不是.Stub()