【问题标题】:Using Moq to mock a repository that returns IQueryable<MyObject>使用 Moq 模拟返回 IQueryable<MyObject> 的存储库
【发布时间】:2011-05-27 18:11:19
【问题描述】:

如何设置我的起订量以返回一些值并让测试服务选择正确的值?

IRepository:

public interface IGeographicRepository
{
    IQueryable<Country> GetCountries();
}

服务:

public Country GetCountry(int countryId)
{
    return geographicsRepository.GetCountries()
             .Where(c => c.CountryId == countryId).SingleOrDefault();
}

测试:

    [Test]
    public void Can_Get_Correct_Country()
    {
        //Setup
        geographicsRepository.Setup(x => x.GetCountries()).Returns()
        //No idea what to do here.

        //Call
        var country = geoService.GetCountry(1); 
        //Should return object Country with property CountryName="Jamaica"

        //Assert
        Assert.IsInstanceOf<Country>(country);
        Assert.AreEqual("Jamaica", country.CountryName);
        Assert.AreEqual(1, country.CountryId);
        geographicsRepository.VerifyAll();
    }

我基本上卡在设置上。

【问题讨论】:

    标签: unit-testing nunit moq


    【解决方案1】:

    您可以做的是编写一个私有辅助方法,该方法将生成 Country 对象的 IQueryable 并让您的模拟返回它。

    [Test]
    public void Can_Get_Correct_Country()
    {
        // some private method
        IQueryable<Country> countries = GetCountries(); 
    
        //Setup
        geographicsRepository.Setup(x => x.GetCountries()).Returns(countries);
    
        //Should return object Country with property CountryName="Jamaica"
        //Call
        var country = geoService.GetCountry(1); 
    
        //Assert
        Assert.IsInstanceOf<Country>(country);
        Assert.AreEqual("Jamaica", country.CountryName);
        Assert.AreEqual(1, country.CountryId);
        geographicsRepository.VerifyAll();
    }
    

    【讨论】:

    • 这就是他们所谓的写stub?所以我必须为所有返回 IQuerable 的存储库函数重写存根?我应该将所有这些存根移动到每个存储库的测试项目内的单独文件中吗?
    • @Shawn:您很可能能够在大多数单元测试中重用相同的存根,不是吗?我会把它放在你的测试课上。
    • 如何在 IQueryable 上使用 Assert?
    • @Shawn:你要断言什么?
    【解决方案2】:

    我建议不要使用 AsQueryable()。它只适用于一些简单的场景,然后才能在 ORM 查询语言上遇到一些特定方法(Fetch、FetchMany、ThenFetchMany、Include、ToFuture 等)。

    最好在内存数据库中使用。下面的链接描述了 NHibernate 单元测试。

    我们可以使用标准的 RDBMS 或使用内存数据库(例如 SQLite)来获得非常快速的测试。

    http://ayende.com/blog/3983/nhibernate-unit-testing

    【讨论】:

      【解决方案3】:

      你不能用AsQueryable()吗?

      List<Country> countries = new List<Country>();
      // Add Countries...
      IQueryable<Country> queryableCountries = countries.AsQueryable();
      
      geographicsRepository.Setup(x => x.GetCountries()).Returns(queryableCountries);
      

      【讨论】:

      • 解释一下?我对这一切都不熟悉。
      • 这也是我模拟 IQueryable 存储库的方式。
      • 这确实使它无法响应 ToArrayAsync
      猜你喜欢
      • 2011-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-28
      • 1970-01-01
      • 2011-10-26
      相关资源
      最近更新 更多