我正在创建一个公开IQueryable的存储库。对我的单元测试进行模拟的最佳方法是什么?
由于我在其余的模拟对象中使用RhinoMocks,我尝试执行以下操作:
IQueryable<MyObject> QueryObject =
MockRepository.GenerateStub<IQueryable<MyObject>>();
这不起作用,所以我尝试这样做:
IQueryable<MyObject> QueryObject =
(new List<MyObject> { new MyObject() }).AsQueryable();
有更好的方法可以做到这一点,还是有任何其他模拟框架构建了对IQueryable的支持?
我的存储库界面如下所示:
public interface IRepository<T> where T : TableServiceEntity
{
IQueryable<T> Table { get; }
void Attach(T existingItem);
void Delete(T itemToDelete);
void Insert(T newItem);
T Load(string partitionKey, string rowKey);
IEnumerable<T> Load(string partitionKey);
IEnumerable<T> Query(IQueryable<T> query);
IEnumerable<T> Last(int count);
T Last();
void Update(T item);
}
以下是我要测试的方法:
public Post LoadPost(int year, int month, int day, string slug)
{
var query = from p in _blogRepository.Table
where
p.PartitionKey == Key.Partition(year, month, day)
&& p.Slug == slug
select p;
var posts = _blogRepository.Query(query.Take(1));
return posts.First();
}
然后这是我现在测试的测试,它将测试LoadPost。
[Fact]
public void LoadWillRetrieveByPartitionKeyAndRowKeyWhenUsingUriFormat()
{
Repository
.Stub(x => x.Query(Arg<IQueryable<Post>>.Is.Anything))
.Return(new List<Post> {_post});
var result = Service.LoadPost(
_post.Year(),
_post.Month(),
_post.Day(),
_post.Slug);
Assert.NotNull(result);
}
代码来自我的AzureBlog项目。
答案 0 :(得分:10)
我通常会完成您在测试中最终完成的工作。在编写测试时,我假设.Net库类正常工作并且不包含错误,因此我可以在测试中使用它们。当我需要测试列表,集合,可查询,字典等时,我只需创建真实的东西并填充测试数据。它使测试更具可读性和更快速,并且说实话,风险是不存在的。
答案 1 :(得分:4)
如果你想模拟你的存储库,你就不会嘲笑IQueryable。相反,模拟存储库的方法以返回可用于运行单元测试的固定的已知值(如第二个示例)。
答案 2 :(得分:2)
我知道这是一个老问题,但只想加2美分。
我对使用SharpLite生成的存储库存在同样的问题,SharpLite是我不时使用的ASP .NET MVC框架。过了一段时间,我发现了一个解决方案,唯一的问题是使用Moq,而不是Rhino Mocks,但可能你可以找到一种方法来适应它。我就如何做到了blog post here。
它基本上创建了一个实现IQueryable并将其用作伪数据背景的列表。希望我能帮忙!
答案 3 :(得分:0)
我不确定这是否会对你有所帮助......但我做了类似于你所说的事情。在我的场景中,我有一个使用存储库的数据上下文类。
我开始创建一个包含IQueryable方法的接口(IRepository)。然后我创建了两个实现此接口的类。一个类使用ORM进行数据操作(DbEntityRepository),另一个类使用类属性(MemoryRepository)。数据上下文类有一个需要IRepository的构造函数。这样做我可以在测试数据上下文时使用MemoryRepository,我可以使用DbEntityRepository作为应用程序。
如果您有兴趣...您可以在codeplex上找到代码:IQToolkitContrib