Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I set up my integration tests to use a test database with Entity Framework?

I am writing integration tests for an application and have not been able to find any best practices on how to set up a test database for my integration suite. I am working on an ASP.NET MVC4 application using Entity Framework code-first.

I can confirm that the tests in my test project talk to the local development database on my machine by default. This is not ideal, as I want to have a fresh database every time I run the tests.

How can I set up my test project so that my tests talk to a separate instance? I'm assuming that it is possible to set up an SQL Server Compact Edition instance, but I'm not sure how to configure this.

like image 534
rouan Avatar asked Dec 13 '12 09:12

rouan


People also ask

Should integration tests use database?

Integration tests focus on testing how separate parts of the program work together. In the context of applications using a database, integration tests usually require a database to be available and contain data that is convenient to the scenarios intended to be tested.

What are the four different ways that we can perform integration testing?

Four key strategies to execute integration testing are big-bang, top-down, bottom-up and sandwich/hybrid testing. Each approach has benefits and drawbacks. Big-bang testing: The big-bang approach involves integrating all modules at once and testing them all as one unit.


1 Answers

Thanks so much to @Justin and @Petro for your answers, which have helped me immensely. The solution I have come up with is a combination of the techniques you suggested. The solution described below provides a new database for each run of the tests, and a separate transaction for each test.

I added a connection string for my test database in the App.config of my Test project:

  <connectionStrings>     <add name ="TestDatabase"      providerName="System.Data.SqlClient"      connectionString="Data Source=(LocalDb)\v11.0;Database=TestDatabase;Integrated Security=True"/>   </connectionStrings> 

I created a base class for my integration tests, to provide setup and teardown. Setup instantiates the context, creates the DB if it doesn't exist yet and starts a transaction. Teardown rolls back the transaction.

public class EntityFrameworkIntegrationTest {     protected MyDbContext DbContext;      protected TransactionScope TransactionScope;      [TestInitialize]     public void TestSetup()     {         DbContext = new MyDbContext(TestInit.TestDatabaseName);         DbContext.Database.CreateIfNotExists();         TransactionScope = new TransactionScope(TransactionScopeOption.RequiresNew);     }      [TestCleanup]     public void TestCleanup()     {         TransactionScope.Dispose();     } } 

Finally, I have a class that takes care of deleting the database after all the tests have run:

[TestClass] public static class TestInit {     // Maps to connection string in App.config     public const string TestDatabaseName = "TestDatabase";      [AssemblyCleanup]     public static void AssemblyCleanup()     {         Database.Delete(TestDatabaseName);     } } 

I should add that I found this blog post about Entity Framework useful for a deeper understanding of what Entity Framework is doing under the hood / by convention.

like image 175
rouan Avatar answered Sep 25 '22 21:09

rouan