Shawn Mclean
Shawn Mclean

Reputation: 57469

Using Moq to mock a repository that returns IQueryable<MyObject>

How to I setup my Moq to return some values and having the tested service select the right one?

IRepository:

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

Service:

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

Test:

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

I'm basically stuck at the setup.

Upvotes: 50

Views: 19547

Answers (3)

Tyler Treat
Tyler Treat

Reputation: 15008

What you can do is write a private helper method that will generate an IQueryable of Country objects and have your mock return that.

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

Upvotes: 0

Ievgen
Ievgen

Reputation: 8086

I suggest do not use AsQueryable(). it works only with some simple scenarios before you meet some specific methods on your ORM query language (Fetch, FetchMany, ThenFetchMany, Include, ToFuture and so on).

Better to use in memory database. Link below describes NHibernate Unit Testing.

We can either use a standard RDBMS or use an in memory database such as SQLite in order to get very speedy tests.

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

Upvotes: 2

Andrew Whitaker
Andrew Whitaker

Reputation: 126072

Couldn't you use AsQueryable()?

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

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

Upvotes: 90

Related Questions