我需要用RhinoMock模拟一个DbSet。我找到了一种方法来模拟IDbSet,但不是DbSet。我找到了使用另一个模拟框架的方法,但我必须使用RhinoMock。有没有人能把它翻译成rhino mock?
我在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;
}谢谢
发布于 2017-07-08 12:39:38
更新
虽然RhinoMocks支持使用相同的模拟来模拟多个接口,正如我在最初的回答中所使用的那样,但它显然不支持显式接口,而DbSet在IQueryable中利用了显式接口。正如@Dosihris在评论中指出的那样,它抛出了一个异常,即
由于CLR处理显式接口实现的方式,我们无法代理此方法。
这似乎是RhinoMocks中嵌入的Castle.DynamicProxy版本(v2.1.0.5967)的一个例外,该版本来自2010年前的版本。较新版本的DynamicProxy支持这一点,因此,如果您真的想要更具冒险精神,可以使用更新版本的DynamicProxy重新编译RhinoMocks。
或者,您可以尝试在测试项目中直接引用DynamicProxy,并使用绑定重定向强制RhinoMocks使用较新的版本。考虑到RhinoMocks版本的历史,可能与较新的DynamicProxy API不兼容,所以这可能不会成功。
或者,您可以迁移到仍在积极维护的框架,例如Moq或NSubstitute (它们都使用较新版本的DynamicProxy)。
这是使用RhinoMocks的等效逻辑:
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()而不是.Expect()。
https://stackoverflow.com/questions/44948798
复制相似问题