C# 如何模拟IQueryable<;T>;

C# 如何模拟IQueryable<;T>;,c#,mocking,rhino-mocks,iqueryable,C#,Mocking,Rhino Mocks,Iqueryable,我正在创建一个公开IQueryable的存储库。在我的单元测试中模拟这一点的最佳方法是什么 由于我将Rhinomock用于其余的模拟对象,因此我尝试执行以下操作: IQueryable<MyObject> QueryObject = MockRepository.GenerateStub<IQueryable<MyObject>>(); 下面是我现在的测试,它将测试LoadPost [Fact] public void LoadWillRetrie

我正在创建一个公开IQueryable的存储库。在我的单元测试中模拟这一点的最佳方法是什么

由于我将Rhinomock用于其余的模拟对象,因此我尝试执行以下操作:

IQueryable<MyObject> QueryObject = 
    MockRepository.GenerateStub<IQueryable<MyObject>>();
下面是我现在的测试,它将测试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);
}
[事实]
使用InguriFormat()时,将通过分区键和工作键检索公共无效加载
{
存储库
.Stub(x=>x.Query(Arg.Is.Anything))
.Return(新名单{u post});
var result=Service.LoadPost(
_年后(),
_月后(),
_post.Day(),
_后鼻涕虫);
Assert.NotNull(结果);
}

代码取自我的项目。

如果您想模拟存储库,就不能模拟IQueryable。相反,模拟存储库的方法,以返回可用于运行单元测试的固定已知值(如第二个示例)。

我不确定这是否有助于您……但我做了一些与您所说的类似的事情。在我的场景中,我有一个使用存储库的数据上下文类

我首先创建了一个包含IQueryable方法的接口(IRepository)。然后我创建了两个类来实现这个接口。一个类使用ORM进行数据操作(DbEntityRepository),另一个类使用类属性(MemoryRepository)。数据上下文类有一个需要IRepository的构造函数。这样做,我可以在测试数据上下文时使用MemoryRepository,也可以在应用程序中使用DbEntityRepository


如果您感兴趣……您可以在codeplex上找到代码:

我通常会做您在测试中最终做的事情。在编写测试时,我假设.Net库类工作正常并且不包含bug,因此我可以在测试中使用它们。当我需要测试列表、集合、查询、字典等时,我只需要创建真实的东西并填充测试数据。它使测试更具可读性,编写速度更快,老实说,风险是不存在的。

我知道这是一个老问题,但我只想加上我的2美分

我对使用SharpLite生成的存储库也有同样的问题,SharpLite是我经常使用的ASP.NETMVC框架。一段时间后,我找到了一个解决方案,唯一的问题是使用Moq,而不是Rhino Mock,但可能你可以找到一种方法来适应它。我对如何做这件事作了详细的讨论


它基本上是创建一个实现IQueryable的列表,并将其用作假数据背景。希望我能帮忙

我从这条路线开始,然后在通用存储库之上创建了一个特定存储库的额外层。这导致了我的域服务->域存储库->通用存储库。如果我能够从域服务->通用存储库进行测试,并且实现细节不会泄漏到域服务中,我会更高兴,因为需要维护和测试的代码更少。我明白你的意思。但是,如果您的问题来自于为您的DomainService编写单元测试,那么我认为您应该嘲笑DomainRepository,不要担心通用存储库(目前)。对DomainService进行单元测试最好通过模拟其依赖项来完成。就DomainService而言,它不应该关心如何实现DomainRepository(即从基类继承)。希望这有帮助!
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();
}
[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);
}