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?

Steve Macdonald
  • 1,745
  • 2
  • 20
  • 34
  • 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). – Steve Macdonald Apr 24 '10 at 12:20

4 Answers4

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.

KallDrexx
  • 27,229
  • 33
  • 143
  • 254
  • 1
    -1 Linq2Objects behaves differently to Linq2Entities. You tests might pass against a List but fail when parsed into SQL by EF. – Casey Burns Nov 17 '10 at 22:14
  • 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. – KallDrexx Nov 18 '10 at 13:29
  • 2
    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. – Casey Burns Nov 22 '10 at 02:50
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!

Casey Burns
  • 1,223
  • 12
  • 15
1

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

mxmissile
  • 11,464
  • 3
  • 53
  • 79
  • 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). – Steve Macdonald Apr 24 '10 at 12:12
  • 2
    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? – SamuelWarren Jul 21 '11 at 20:03
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

Community
  • 1
  • 1
kenno
  • 333
  • 2
  • 7