tags:

views:

267

answers:

3

[Edit (Haren): Duplicate]

I'm looking for a way to automatically wrap my NUnit integration tests in a DB transaction, so that changes made by the test are automatically rolled back when the test ends. Ideally, I would decorate certain test methods with a custom attribute that would cause NUnit to create a transaction when the test starts and roll it back when the test ends... I can write the attribute, but I don't know where to add a check for it.

The test DB is 3GB in size, so restoring it at the start of each test isn't an option. I know I can manually create a transaction in the body of each test, but I'm looking for something more elegant.

Perhaps there's an IL-rewriting tool (an AOP framework, maybe) that can do this for me? Anyone have any suggestions?

A: 

Spring.net?

I come from a Java/JUnit background, but I know that in Java you could do this using Springframework.

(You also will have to obtain your test from the ApplicationContext/BeanFactory in order to apply AOP to it).

leeand00
+1  A: 

There are two recommendations. The first is to use the SetUp and TearDown attributes to start the transaction and roll it back when done. The documentation to do so in NUnit is here:

http://www.nunit.org/index.php?p=setup&r=2.4.8

If you don't want to use that, the other option I see is to code it in every method, but use a TransactionScope instance in a using statement to create the transaction (the provider should auto-enlist).

Of course, you can create the TransactionScope instance in the SetUp and TearDown methods as well.

casperOne
In the time since I wrote this question I've used both the "using" block and the setup/teardown approach. I use "using" when I only need to rollback certain tests in a fixture. If I want this behavior for all of my tests, I add a custom "RollbackEveryTest" attribute to the test class. I use setup/teardown of my base test class to check for the attribute and manage the transaction accordingly. It's not perfect, but it works for the common case.
Seth Petry-Johnson
+2  A: 

Aren't you going to run into trouble with nested transactions here? As I understand it most DB's don't support transactions within transactions. So if the code under test uses transactions at all (I'd think if you are using a DB that supports transactions, you'd be using them), then what you really want is nested transactions, which (I'm told) most DBs don't directly support.

Michael Kohne
That's a valid point. In my case I'm only concerned about SQL Server, but I'm giving your response a "+1" since other readers might not be able to make that distinction up front.
Seth Petry-Johnson