EF4 - possible to mock ObjectContext for unit testing?
Asked Answered
I

4

7

Can it be done without using TypeMock Islolator? I've found a few suggestions online such as passing in a metadata only connection string, however nothing I've come across besides TypeMock seems to truly allow for a mock ObjectContext that can be injected into services for unit testing. Do I plunk down the $$ for TypeMock, or are there alternatives? Has nobody managed to create anything comparable to TypeMock that is open source?

Italianate answered 24/4, 2010 at 3:24 Comment(1)
One suggestion I've seen is to break the rules re testing against the db. The guy said he uses CreateDatabase() to create a "mock" db instance on the fly locally. In general I want to avoid this as we broke this rule on a prior project and it didn't work out so well. It was OK up to about ~600 tests, but at the end with > 2000 tests it was totally useless for true TDD and we ran the tests in "batch mode" now and then (took 5 minutes or more to run them).Italianate
F
4

I'm unit testing EF4 easily without mocking. What I did was create a repository interface using the code from http://elegantcode.com/2009/12/15/entity-framework-ef4-generic-repository-and-unit-of-work-prototype/ as a basis I then created an InMemoryRepository<T> class that used the IRepository interface. I then replaced the IObjectSet<T> with a List<T> inside of the class and changed the retrieval methods accordingly.

Thus if you need to do unit testing, pass in the InMemoryRepository rather than the DataRepository.

Finely answered 21/5, 2010 at 17:57 Comment(3)
-1 Linq2Objects behaves differently to Linq2Entities. You tests might pass against a List<T> but fail when parsed into SQL by EF.Knitted
There's no way to get passed that without accessing the database, so I am not sure what your point is. Mocking does not mean your Linq2Entities will always be valid and work properly as well.Finely
Encapulate your queries and test them against a real database. Then mock them when testing your business logic. Therefore each query is a reusable component you know for a fact will work. And your business logic is tested without requiring a database that is in the expected state.Knitted
K
3

Put your Linq2Entity query behind an interface, unit test it in isolation against a real database.

Write tests for your business logic with mocks for your query interfaces. Don't let Linq bleed into your business logic!

Don't use the RepositoryPattern!

Knitted answered 17/11, 2010 at 22:23 Comment(0)
J
1

Wrap the ObjectContext in a proxy class. Then inject that into your classes.

Jocosity answered 24/4, 2010 at 4:5 Comment(2)
Yes I tried that, and it is a possibility -- however all of these approaches using proxies have their own limitations. Linq works differently for one thing (Linq to objects is used, versus Linq to entities).Italianate
TRue, but expecting your Unit tests to pick up differences in different Linq implementations seems somewhat overboard for Unit Tests. That more in the integration test arena don't you think?Sibbie
P
0

I don't think the repository pattern is the only answer to the question (it avoids the problem, sure)

I liked this answer - I think more appropriate for introducing tests to an existing codebase Creating Interface for ObjectContext

Parallelism answered 10/7, 2012 at 0:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.