How to force EF LINQ query generation without execution

不想你离开。 提交于 2019-12-23 04:04:43

问题


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?


回答1:


No there is no way to do that - unless you are going to build your own provider which in turn is not the solution because you must test the real provider not a custom implementation which will not be used in the real code. I discussed it here and here. One more related answer about repository itself.

Simply you can't test database mapping and persistence without doing database mapping and persistence. There is some very strange belief that testing application means writing unit tests. That is wrong definition. Testing application means writing tests and unit tests are just one of many test types but they can't test everything. You need to combine them with other types of tests. The correct approach for this scenario can be integration tests which doesn't have to run every time but can be scheduled on the build server.



来源:https://stackoverflow.com/questions/5756168/how-to-force-ef-linq-query-generation-without-execution

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!