Nesting transaction scopes for integration tests using Rhino Commons UnitOfWork

1.1k views Asked by At

I'm trying to set up a integration test class that wraps each test in a transaction. This way I can rollback the transaction after each test instead of resetting the DB before each test.

I also want to be able to use transactions in the integration tests themselves.

I am using NHibernate and the Rhino Commons UnitOfWork for the the project. I am using MSTest for the tests.

I want something like this:

[TestInitialize]
public void TestInit() {
    // create outer transaction scope
    UnitOfWork.Start();
    UnitOfWork.Current.BeginTransaction();
}

[TestCleanup]
public void TestCleanup() {
    // rollback outer transaction
    UnitOfWork.Current.Dispose();
}

[TestMethod]
public void IntegrationTest() {
    using (UnitOfWork.Start(UnitOfWorkNestingOptions.CreateNewOrNestUnitOfWork)) {
        UnitOfWork.Current.BeginTransaction();

        // integration test code

        UnitOfWork.Current.TransactionalFlush();

        // possibly more transactions
    }
}

This is the first time I have used NHibernate, Rhino Commons, and MSTest. I am not clear on the behavior of sessions with nested Rhino Commons UnitOfWorks. What I have here does not rollback the changes from the integration test.

I tried using TransactionScope from System.Transactions, but get the following error when the UnitOfWorks end:

System.InvalidOperationException: Disconnect cannot be called while a transaction is in progress..

So here are my questions:
Is there a way to get this behavior with UnitOfWork in Rhino Commons? If not, should I just reset the database before each test or is there another way to nest transactions that plays nicely with the UnitOfWork?

Thank you.

1

There are 1 answers

0
Lee KW On

I believe UnitOfWork.Start().BeginTransaction() returns a RhinoTransaction. So to make it more clear you can try to rewrite the code as this:

using(IUnitOfWork uow = UnitOfWork.Start(UnitOfWorkNestingOptions.CreateNewOrNestUnitOfWork))
{
    RhinoTransaction tx = uow.BeginTransaction();
    .
    .
    .
    .
    tx.Rollback();
}

Be warned though, I have not tried the code above, let me know if it works.