Носорог Rhino генерирует исключение «Аргументы обратного вызова не соответствуют делегату аргументов метода» в методе do - PullRequest
1 голос
/ 27 января 2011

Я использую moh Rhino для изменения поведения NHL-библиотеки NHibernate, чтобы при вызове транзакции коммита код изменял поведение, поэтому транзакция откатывается. Я делаю это потому, что для интеграционного тестирования я не хочу добавлять какие-либо данные в базу данных.

Вот мой тестируемый метод / класс:

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;
                }

            }
        }
    }

}

Это тестовый код:

  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;
        }
    }

Я получаю сообщение об ошибке «Аргументы обратного вызова не соответствуют делегату аргументов метода», которые появляются во 2-й строке после начала блока try, catch.

Может кто-нибудь помочь мне понять значение этого сообщения об ошибке и что я могу сделать, чтобы решить эту проблему? Или у кого-нибудь есть предложения, как проводить интеграционное тестирование с Nhibernate?

Al

Ответы [ 2 ]

7 голосов
/ 27 января 2011

Я не использовал RhinoMocks, но я использовал другие фиктивные фреймворки.Я думаю, проблема в том, что ваш метод Save принимает один параметр, но делегат, который вы указали для метода обратного вызова Do, не принимает аргумент.

Эта строка, вероятно, должна выглядеть следующим образом:

SessionStub.Stub(ss => ss.Save(Arg<EmployeeDataContext>.Is.Anything)).Do(arg => Session.Save(employee))
5 голосов
/ 27 января 2011

Ответ Мэтта верен, но также рассмотрите возможность использования WhenCalled вместо Do . Его гораздо проще использовать, когда вам на самом деле не нужно использовать фактические параметры, переданные, как в вашем случае.

...