开发者

Replicating LINQ to Entities behavior in unit tests that use LINQ to Object

In my solution I have unit tests which do not depend on the database but rather mocks and integration tests which have external dependencies like the database.

When I am doing unit tests with mocks, LINQ to Object is used. When 开发者_JAVA技巧the integration tests or the real program runs, LINQ to Entities is used and it is more strict than LINQ to Object.

Is there a way to replicate LINQ To Object stricter behavior in my unit tests ?


Once your unit tested logic works with IQueryable provided by EF you simply cannot test it with unit tests by mocking EF. That will always lead to switching from linq-to-entities to linq-to-objects. In case of something simplified the correct way to handle this in unit test is writing a fake instead of mock. Fake would simulate behavior of the dependency. In this case writing a fake means writing EF provider working on in-memory collection in exactly same way as real provider works with the database. Writing such provider is probably project itself.

Because of that once your logic contains linq-to-entities queries you should always test it with integration tests or refactor the code so that query itself is in separate method (tested by integration tests) and former logic now has dependency on the class containing the method instead on EF itself - this leads to repository pattern where IQueryalbe is not exposed but repository exposes method for each needed query operating on some entity. I personally don't like this kind of repositories. Here is recent discussion about different repository implementations.

If you decide to use integration tests changing database to in-memory one can be possible with EFv4.1 and code first where you simply change connection string to SQL Compact 4 and it will work (unless you are using some special direct SQL calls or demanding some special SQL types in mapping). In case of EF with EDMX file it will not work, because EDMX file is tightly coupled with exact database version. Having special EDMX just for unit testing is not an option because you would again test different code.

Here is set of related questions discussing challenges with unit testing EF code and repositories.


You can use repository pattern to define IRepository interface, in your actual code, you can implement it using Entity Framework, and in your unit test, you can use mock framework to return the objects for testing.


If you want your unit tests for layer that talks with database to have the real value and all behaviors like in production code, you need to talk with database. It may be considered as breaking the rule of having no dependencies in unit test, but there's no other way to have LINQ to Entities doing its job than letting it talk with real database. It may (and probably should) be an in-memory database - see for example how is Ayende doing it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜