- Posted by Ian Suttle on August 20, 2009
- Filed under
I was working with some integration tests recently and had an epiphany: Why don't I use transactions in a test to reset data? I'm referring to a case where an integration test does something like write a new row to a database table. If I'm running these tests over and over those rows add up unnecessarily. Wrapping the integration test with something like TransactionScope in .NET makes resetting this data real easy.
Take this hypothetical test in to consideration:
[Test]
public void AddDatabaseRow()
{
DataContext data = new DataContext();
SomeItem item = data.SaveItem(1, "abcd");
Assert.IsNotNull(item, "Return data was null");
Assert.AreEqual(1, item.UserID, "UserID did not match");
}
If I ran this test over and over again I'd have a duplicate table record added over and over again. Sometimes that's not even possible when unique constraints are enforced such as having to have a unique email address. The argument can be made that DataContext should be a mock object and not a live connection I suppose. For argument's sake let's say there's a valid reason for doing an integration test this way:).
Now let's look at a test using a transaction to reset the data when we're done.
[Test]
public void AddDatabaseRow()
{
DataContext data = new DataContext();
using (TransactionScope trans = new TransactionScope())
{
SomeItem item = data.SaveItem(1, "abcd");
Assert.IsNotNull(item, "Return data was null");
Assert.AreEqual(1, item.UserID, "UserID did not match");
}
}
Using TransactionScope here performs a rollback after the assertions have been made and avoids permanently saving the database record to the table.
What do you think about this? Is there a better way to go about achieving the same goal of not committing records often?