In the past, I've written unit tests for simple CRUD operations when creating data access/repository code that look something like this:
using(var connection = new WhateverConnection(connectionString))
{
connection.Open();
using(var transaction = connection.BeginTransaction())
{
try
{
//test the CRUD operation
}
finally
{
//gets rid of any stuff created during the test
transaction.Rollback();
}
}
}
I was messing around with EF4 Code First today, and I realized that I have no idea how this testing scenario translates in the Entity Framework lexicon. It seems that, if I call DbContext.SaveChanges()
, it saves and commits, regardless of whether or not AcceptAllChanges()
was called. Even using ObjectContext
instead of DbContext
, I can't figure out how this simple test scenario can be recreated without manually cleaning up any mock/test objects created. I did read this article on MSDN, but TransactionScope
doesn't really have a Rollback
type method either. Do I use TransactionScope
and never call Complete
? Is there another method or manner of using DbContext and/or ObjectContext in order to Rollback during unit tests? Do I need to completely re-adjust my thinking for TDD with EF4 Code First?
ObjectContext
itself does not expose transactional behavior. You have to wrap EF code in transaction by yourself. The easy way to do it is usingTransactionScope
. If you don't callComplete
method on the scope and dispose it, it will perform rollback. We are usually using base class for this type of integration tests:All test classes derive from this class.
TestInitialize
is called before eachTestMethod
in derived class andTestCleanup
is called after eachTestMethod
so your tests don't have to deal with transaction at all.