Search code examples
c#nhibernatetestingdelegatesrhino-mocks

Rhino mocks throws exception of "Callback arguments didn't match the method arguments delegate" on the do method


I'm using Rhino mocks to change the behaviour of a NHibernate DAL so that when the commit transaction is called by the code the mock framework changes the behaviour so the transaction is rolled back. The reason i am doing this is that for integration testing but i don't want to add any data to the database.

Here is my the method/class under test:

public class NHibernateDALSave<T> : IBaseDALSave<T> where T : class
{
    protected ISession _session;
    protected ISessionFactory _sessionFactory;

    public NHibernateDALSave()
    {
        _sessionFactory = new Configuration().Configure().BuildSessionFactory();
    }

    public NHibernateDALSave(ISessionFactory sessionFactory)
    {
        _sessionFactory = sessionFactory;
    }

    public void OpenSession()
    {
        if (_sessionFactory == null)
        {
            _sessionFactory = new Configuration().Configure().BuildSessionFactory();
        }

        _session = _sessionFactory.OpenSession();
    }

    public virtual int Save(T objectToSave)
    {
        this.OpenSession();
        using (_session)
        {
            using (ITransaction tx = _session.BeginTransaction())
            {
                try
                {
                    Int32 NewId = Convert.ToInt32(_session.Save(objectToSave));
                    _session.Flush();
                    tx.Commit();
                    return NewId;
                }
                catch (Exception)
                {
                    tx.Rollback();
                    throw;
                }

            }
        }
    }

}

This is the test code:

  public void SaveEmployee_Blank_Success()
    {
        //setup employee object to save
        EmployeeDataContext employee = new EmployeeDataContext();
        employee.Person = new PersonDataContext();
        employee.PayRollNo = "12345";
        employee.Person.Surname = "TEST";

        //stub classes
        ISessionFactory SessionFactoryStub = MockRepository.GenerateMock<ISessionFactory>();
        ISession SessionStub = MockRepository.GenerateMock<ISession>();
        ITransaction TranStub = MockRepository.GenerateMock<ITransaction>();

        //Actual classes
        ISessionFactory sessionFactory = new Configuration().Configure().BuildSessionFactory();
        ISession Session = sessionFactory.OpenSession();
        ITransaction Tran = Session.BeginTransaction();

        try
        {
            //Configure to prevent commits to the database
            SessionStub.Stub(ss => ss.BeginTransaction()).Return(TranStub);
            SessionStub.Stub(ss => ss.Save(Arg<EmployeeDataContext>.Is.Anything)).Do((Action)delegate { Session.Save(employee); });
            SessionStub.Stub(ss => ss.Flush()).Do((Action)delegate { Session.Flush(); });

            TranStub.Stub(ts => ts.Commit()).Do((Action)delegate { Tran.Rollback(); });
            TranStub.Stub(ts => ts.Rollback()).Do((Action)delegate { Tran.Rollback(); });

            SessionFactoryStub.Stub(sf => sf.OpenSession()).Return(SessionStub);

            NHibernateDALSave<EmployeeDataContext> target = new NHibernateDALSave<EmployeeDataContext>(SessionFactoryStub);
            target.Save(employee);
        }
        catch
        {
            Tran.Rollback();
            throw;
        }
    }

The error I am getting is "Callback arguments didn't match the method arguments delegate" which occurs on the 2nd line after the start of the try, catch block.

Can anyone help me with the meaning of this error message and what i can do to resolve this? Or does anyone have an suggestions of how to carry out integration testing with Nhibernate?

Al


Solution

  • Matt's answer is correct, but also consider using WhenCalled, instead of Do. It's much easier to use, when you don't actually need to use the actual parameters passed in as in your case.