18 June 2014. The project coordinators will no longer be contributing to this project. Please have a look at
, a mature unit test suite for EF based on the same principal as this project.
Unit test Entity Framework 4.3+ and confirm you have valid LINQ-to-Entities code without any need for a database connection.
I agreed with Ladislav Mrnka
* for a long time that you
with a live DB for LINQ-to-Entities queries because of the problems with distinction between LINQ-to-Objects (which will be used for any kind of mock DbContext) and LINQ-to-Entities.
Then I realized the problem is, we're mocking the wrong thing! We want a real
with all the EF stuff that goes with it to test our logic, we just don't want that context to depend on a real database. So what we really need to mock is the
that the context uses internally to talk to a database.
Because we're using a real DbContext
, we cannot mock the internals directly, however,
supports a DefaultConnectionFactory
which creates the
"The new configuration section allows you to specify a default connection factory that Code First should use to locate a database to use for a context. The default connection factory is only used when no connection string has been added to the configuration
file for a context."
If we inject a factory which creates a fake connection before building our context, we can create a unit test of EF code which actually uses LINQ-to-Entities and no database! A couple of notes:
- EF relies on the DbProviderServices and DbProviderManifest to do a lot of the translation between EDM types and SQL types, among other important things. My code reflects onto the SqlProviderServices and SqlProviderManifest (declared Friend inside of SqlClient
in System.Data.Entity.dll) to do this work. To make the code work for non-SQL db's, you'll have to do similar reflection for their client.
- The default IDatabaseInitializer is
CreateDatabaseIfNotExists. That requires a lot of extra mocking inside your DbConnection to "pretend" to create a database. To avoid this, I created a DoNotCreateDatabaseInitializer which does nothing in the
InitializeDatabase method and reduced the mocking my fake conneciton needs.
- NOTE: Lots of well known .NET / EF developers subscribe to the integration testing only mentality, Ladislav just happens to be the most vocal AFAIK.
To use the project, just reference FakeDbConnection in your project and call
before you create context object to test. You cannot verify data because we're not mocking the DB here, but you can verify the code makes valid SQL. Here's
a full sample (in VB w/ NUnit):
Public Class YourTestClass
Public Sub Your_Test()
Dim context As New YourContextType("sql server year")
Dim actualData As IEnumerable(Of YourModelType) = context.YourModels.Where(Function(YourModel) YourModel.ID = 1)
'Assert we have a valid EF query
Assert.IsTrue(TypeOf actualData Is Entity.Infrastructure.DbQuery(Of YourModelType))
'Assert it can compile to valid SQL