web-dev-qa-db-ja.com

Moqを使用して、IQueryable <MyObject>を返すリポジトリをモックします

いくつかの値を返すようにMoqを設定し、テストされたサービスに適切な値を選択させるにはどうすればよいですか?

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();
    }

私は基本的にセットアップで立ち往生しています。

37
Shawn Mclean

AsQueryable() を使用できませんでしたか?

List<Country> countries = new List<Country>();
// Add Countries...
IQueryable<Country> queryableCountries = countries.AsQueryable();

geographicsRepository.Setup(x => x.GetCountries()).Returns(queryableCountries);
70
Andrew Whitaker

あなたができることは、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();
}
0
Tyler Treat

AsQueryable()は使用しないことをお勧めします。 ORMクエリ言語で特定のメソッド(Fetch、FetchMany、ThenFetchMany、Include、ToFutureなど)に遭遇する前に、いくつかの単純なシナリオでのみ機能します。

メモリデータベースで使用する方が良いです。以下のリンクは、NHibernateユニットテストについて説明しています。

非常に高速なテストを行うために、標準のRDBMSを使用するか、SQLiteなどのインメモリデータベースを使用することができます。

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

0
Ievgen Martynov