views:

314

answers:

2

Hi, I've implemented unit testing along the lines of this article with a fake object context and IObjectSet with POCO in EF4.

http://blogs.msdn.com/adonet/archive/2009/12/17/test-driven-development-walkthrough-with-the-entity-framework-4-0.aspx

But I'm unsure how to implement a couple of methods on my fake object context for testing. I have CreateQuery and ExecuteFunction methods on my object context interface so that I can execute ESQL and Stored Procedures but I cant (easily) implement them in my fake object context.

An alternative would be to use a test double of my repository instead of a double of my object context as suggested here:

http://social.msdn.microsoft.com/Forums/en-US/adonetefx/thread/c4921443-e8a3-4414-92dd-eba1480a07ad/

But this would mean my real repository isnt being tested and would seem to just bypass the issue.

Can anyone offer any recommendations?

+4  A: 

As far as I can tell from the question, you are trying to test too much at the same time. Keep the Single Responsibility Principle in mind.

When we unit test, we use abstract Repositories to abstract the data access code away from the rest of the application. From this perspective, we are only testing the consumers of the Repositories, not any concrete Repository at all. Such consumers should care only about the Repositories, and not at all about any 'object context' - that would be a Leaky Abstraction.

Imagine that you are unexpectedly being asked to wire your Repository consumers up to a completely different data layer (e.g. a REST-based service). In such cases, even an abstract object context makes no sense. You may not ever expect this to happen, but even so, the thought experiment alone is a pretty good indicator of a Leaky Abstraction.

The object context is an implementation detail of your concrete Repository implementation that uses EF. Other implementations may not need an object context at all.

That said, you may still want to test the EF implementation itself. That may make a lot of sense, but that's a different unit test suite with an entirely different purpose. Instead of testing the consumers of your abstract Repositories, you are now testing a concrete implementation of a Repository. In this case, there's no need to go through the interfaces - you can talk directly to the concrete types here.

Mark Seemann
great answer imo
John Nicholas
A: 

Is it possible to test the actual Repositories with an in memory database such as SQLite? There exist an SQLite provider for Entity Framework.

It seems like the SSDL section in the edmx file is coupled to a provider. If you generate the model from a Sql-server database the provider="System.Data.SqlClient" will be set. This will also be set if you generate a sql-server database from an entity model.

What i really would like to to is to make my production code use System.Data.SqlClient provider and my unit tests to use System.Data.SqLite provider.

Marcus