Artem A
Artem A

Reputation: 2448

Moq setup doesn't work for interface method and enters the moqed method with IQueryable result

I have problems with mocking a method named Query that returns an interface IQueryable, and I don't know why.

The method I try to mock with Moq framework:

public class ObjectContextRepository : IObjectContextRepository
    {
        .....
        private ObjectContext _objectContext = null;      
        public IQueryable<TEntity> Query<TEntity>() where TEntity : class
        {
// Moq Setup doesn't work and debugger enters this code:
            return ObjectContext.CreateObjectSet<TEntity>();
        }
...
}

the test example:

ObjectContextRepositoryFactory = new Mock<IObjectContextRepositoryFactory>();
ObjectContextRepositoryFactory.Setup(x => x.NewInstance(false))
                                          .Returns(new ObjectContextRepository(It.IsAny<string>()));

CurrencyRateManager = new CurrencyRateManager(new ObjectContextRepositoryFactory("connection"));

ObjectContextRepository = new Mock<IObjectContextRepository>();
CurrencyExchangeRate rate1 = new CurrencyExchangeRate {EXCHANGE_DATE = new DateTime(2012, 09, 07)};
CurrencyExchangeRate rate2 = new CurrencyExchangeRate {EXCHANGE_DATE = new DateTime(2012, 09, 06)};

IList<CurrencyExchangeRate> list = new List<CurrencyExchangeRate> { rate1, rate2 };

// I wait that Query() method will return me  a list with rates. 
ObjectContextRepository.Setup(x => x.Query<CurrencyExchangeRate>()).Returns(list.AsQueryable());

using (IObjectContextRepository context = ObjectContextRepositoryFactory.Object.NewInstance())
            {
// Mock doesn't work and debugger enters custom method context.Query<>() and throws an exception
var maxDateQuery = context.Query<CurrencyExchangeRate>()
                    .Where(c => c.EXCHANGE_DATE < new DateTime(2012, 09, 07));
            }

PS. Yes, I know, that I have to use the integration tests, but it's my task.

Upvotes: 1

Views: 1361

Answers (2)

Artem A
Artem A

Reputation: 2448

Sometime it's very effective to stop exploring problem and post a question. The answer comes quickly....

the reason was in Object property of Mocked objects. I changed

ObjectContextRepositoryFactory = new Mock<IObjectContextRepositoryFactory>();
ObjectContextRepositoryFactory.Setup(x => x.NewInstance(false))
                                          .Returns(new ObjectContextRepository(It.IsAny<string>()));

CurrencyRateManager = new CurrencyRateManager(new ObjectContextRepositoryFactory("connection"));

to

        ObjectContextRepository = new Mock<IObjectContextRepository>();

        ObjectContextRepositoryFactory = new Mock<IObjectContextRepositoryFactory>();
        ObjectContextRepositoryFactory.Setup(x => x.NewInstance(false))
                                      .Returns(**ObjectContextRepository.Object**);

        CurrencyRateManager = new CurrencyRateManager(**ObjectContextRepositoryFactory.Object**);

and it works.

Upvotes: 0

Sergei Rogovtcev
Sergei Rogovtcev

Reputation: 5832

Your factory returns new ObjectContextRepository(It.IsAny<string>()) instead of your mock (which is even defined later that your factory). So your test executes against real implementation, not mock.

BTW, there's no sense in using It.IsAny<string>() inside Returns, it does nothing.

Upvotes: 2

Related Questions