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 o
Just setup a connection string in the app.config of your unit test project that points to the new DB instance.
You can then use the initialisation and cleanup methods in your test class to create and delete the DB.
The connection string is just the usual, e.g.
<add name="UnitTestDBConnection" connectionString="Data Source=(local);Initial Catalog=UnitTestDB;Integrated Security=SSPI;" providerName="System.Data.SqlClient"/>
Then to create the DB, once per test, you could do:
YourContext _ctx;
[TestInitialize]
public void Initiaslise()
{
YourNameDbInitialise initialiser = new YourNameDbInitialiseForTest();
Database.SetInitializer(initialiser);
_ctx = new YourNameContext();
initialiser.InitializeDatabase(_ctx);
}
and this to delete at the end of each test
[TestCleanup]
public void Cleanup()
{
Database.Delete("YourName");
}
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.
If you are using NUnit, you could use Setup/Teardown
attribute with TransactionScope
to not commit your changest to the database:
[SetUp]
public void SetUp()
{
transaction = new TransactionScope();
}
[TearDown]
public void TearDown()
{
if(transaction != null)
transaction.Dispose();
}
If you are using some other unit test framework it should have simmilar attributes. I would recomend creating a base class DbItegrationTest
for all your integration test fixtures so if you derive from this class all test methods won't do commits to database.
To configure Entity Framework for other database please override db connection string in your test assembly.