代码之家  ›  专栏  ›  技术社区  ›  Aaron Weiker

如何模仿iqueryable<t>

  •  33
  • Aaron Weiker  · 技术社区  · 16 年前

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

    由于我对其他模拟对象使用犀牛模型,因此我尝试执行以下操作:

    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 项目。

    4 回复  |  直到 14 年前
        1
  •  10
  •   Grzenio    16 年前

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

        2
  •  4
  •   PatrickSteele    16 年前

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

        3
  •  2
  •   David Conde    14 年前

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

    我对Sharplite生成的存储库也有同样的问题,它是我经常使用的ASP.NET MVC框架。一段时间后,我发现了一个解决方案,唯一的问题是使用MOQ,而不是犀牛模型,但可能你可以找到一种方法来适应它。我做了一个 blog post here 关于如何做。

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

        4
  •  0
  •   Tom Brothers    16 年前

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

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

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