I have a nicely decoupled app and dependency-injected app that uses Entity Framework 4.1 CodeFirst to expose IQueryable through a repository pattern. It's easy enough to mock the underlying datastore when testing the repository clients, however a certain class of bug is not being caught:
The repository clients are free to layer their own LINQ predicates, joins, etc on top of what the repository returns:
{
_myRepository.FindAll().Where( x => x.Id == 3 && SomeMethod(x.Name) == "Hello" );
}
This kind of query will succeed in a unit test that mocks _myRepository, because mock returns an in-memory collection of entities and LINQ-to-Objects is happy to call the method "SomeMethod". It will fail against the real data-store because "SomeMethod" does not translate to SQL in LINQ-to-Entities.
I'm trying to figure out a way that I can both mock the dataset and cause the real EF query provider to generate (but not execute) the SQL. Why? Because the tests are supposed to be fast and I don't want them hitting a real database if at all possible. Generating the SQL will flush out translation issues like this.
So far, I have not been able to figure out how to do this, because in my unit tests, I am ultimately not in control of when the query gets materialized. I'm thinking I need to either provide my own version of IQueryable and the various LINQ Queryable extension methods or try and hook in via the provider mechanism (using the sample from a couple of years ago that does Caching/Tracing providers.) Both of these seem like a lot of work. Any ideas on how to achieve this?