I am using NHibernate and Rhinomocks and having trouble testing what I want. I would like to test the following repository method without hitting the database (where _session is injected into the repository as ISession):
public class Repository : IRepository
{
(... code snipped for brevity ...)
public T FindBy<T>(Expression<Func<T, bool>> where)
{
return _session.Linq<T>().Where(where).FirstOrDefault();
}
}
My initial approach is to mock ISession, and return an IQueryable stub (hand coded) when Linq is called. I have a IList of Customer objects I would like to query in memeory to test my Linq query code without hitting the db. And I'm not sure what this would look like. Do I write my own implementation of IQueryable? If so, has someone done this for this approach? Or do I need to look at other avenues?
Thanks!
You can use Moq to create mock objects that simulate or mimic a real object. Moq can be used to mock both classes and interfaces.
Mocking is a process that allows you to create a mock object that can be used to simulate the behavior of a real object. You can use the mock object to verify that the real object was called with the expected parameters, and to verify that the real object was not called with unexpected parameters.
Moq is a mocking framework built to facilitate the testing of components with dependencies. As shown earlier, dealing with dependencies could be cumbersome because it requires the creation of test doubles like fakes. Moq makes the creation of fakes redundant by using dynamically generated types.
A mock version of something is an object that can act like the real thing but can be controlled in test code. Moq (pronounced “mok u” or “mock”) is a library available on NuGet that allows mock objects to be created in test code and it also supports . NET Core.
How I've done this test is to not pass the expression to the repository, instead expose IQueryable giving the repository an interface such as:
public interface IRepository<T>
{
IQueryable<T> All();
// whatever else you want
}
Easily implemented like so:
public IQueryable<T> All()
{
return session.Linq<T>();
}
This means that instead of calling your method on the repository like:
var result = repository.FindBy(x => x.Id == 1);
You can do:
var result = repository.All().Where(x => x.Id == 1);
Or the LINQ syntax:
var result = from instance in repository.All()
where instance.Id == 1
select instance;
This then means you can get the same test by mocking the repository out directly which should be easier. You just get the mock to return a list you have created and called AsQueryable() on.
As you have pointed out, the point of this is to let you test the logic of your queries without involving the database which would slow them down dramatically.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With