Chen Kinnrot
Chen Kinnrot

Reputation: 21015

testing entity mapping of NHibernate

i'm building some basic crud methods for my fluently mapped entities.

i just wanna know if there is a simple way to make the transaction to perform a rollback when i'm running the cud test methods ?

the code that being tested perform the commit inside

here is a create sample:

 public int? Create(IIdentifiable entity)
    {
        int? newId = null;
        using (ISession session = SessionFactoryProvider.NewSession)
        using (ITransaction transaction = session.BeginTransaction())
        {
            object newObj = session.Save(entity);
            newId = (int?)newObj;
            transaction.Commit();
        }

        return (int?)newId;
    }

Upvotes: 1

Views: 383

Answers (4)

Mike Valenty
Mike Valenty

Reputation: 8981

For integration testing, I use a session decorator to auto commit and evict the entity. You could adapt it for your situation:

public class AutoCommitAndEvictSession : SessionDecorator {

    public AutoCommitAndEvictSession(ISession session)
        : base(session) { }

    public override object Save(object obj) {
        object result;
        using (var tx = Session.BeginTransaction()) {
            result = Session.Save(obj);
            tx.Commit();
        }
        Session.Evict(obj);
        return result;
    }

    public override void Update(object obj) {
        CommitAndEvict(base.Update, obj);
    }

    public override void Delete(object obj) {
        CommitAndEvict(base.Delete, obj);
    }

    private void CommitAndEvict(Action<object> action, object entity) {
        using (var tx = Session.BeginTransaction()) {
            action.Invoke(entity);
            tx.Commit();
        }
        Session.Evict(entity);
    }
}

You can find more details on usage with examples here: http://www.agileatwork.com/integration-testing-with-nhibernate/

Upvotes: 0

Ben
Ben

Reputation: 562

If you're using xUnit.net, there's an AutoRollback attribute in the contrib project. If you're open to using System.Transactions then you can create a new transaction before the session.Open() and session should autoenlist (unless you've set ado.net to not autoenlist). Then just abandon at the end.

I did something similar to this a (long) while ago:

public class TransactionalTest
{
    public TransactionalTest()
    {
        Transaction.Current = new CommittableTransaction();
    }

    ~TransactionalTest()
    {
        if (Transaction.Current != null &&
            Transaction.Current.TransactionInformation.Status !=
            TransactionStatus.Committed)
        {
            Transaction.Current.Rollback();
        }
    }
}

Then just have your test extend TransactionalTest. But, I think NUnit, MbUnit and xUnit.net all support transactional tests out of the box or with a contrib project.

Upvotes: 2

mxmissile
mxmissile

Reputation: 11673

Check FUBUMVC Contrib for a great NHibernate CRUD testing method.

Upvotes: 1

Frederik Gheysels
Frederik Gheysels

Reputation: 56934

Hmm, I don't think that it is a good idea to let your method create a session and perform transaction handling .... Unless that method is also a service boundary.

Suppose you want to create multiple entities in one and the same transaction, how are you going to handle that ?

Upvotes: 0

Related Questions