我需要用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;
}
由于
答案 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()
。