Rhinomocks: я не могу правильно использовать AssertWasCalled

1

У меня возникли некоторые проблемы с использованием RhinoMocks, чтобы выяснить, вызывает ли вызов метод в моем классе под тестированием, также вызывается определенное количество других методов. Мой класс для тестирования:

public class OrderMessageHandler : IHandleMessages<UpdateOrder>
{

    public virtual IRepository Repository { get; set; }

    public void Handle(UpdateOrder message)
    {
        if (!message.Order.Confirmed) return;
        using (var om = new OperationManager())
        {
            try
            {
                om.BeginOperation();
                LVR.Order.Model.OrderHeader order = ConvertToLocalOrderHeader(message.Order);
                Repository.SaveUpdate(order);
                om.CommitOperation();
            }
            catch (Exception ex)
            {
                om.RollbackOperation();
                // other stuff here
            }
        }
    }

    internal virtual LVR.Order.Model.OrderHeader ConvertToLocalOrderHeader(Protocol.DTO.OrderHeader order)
    {
        // do stuff here, and call Repository.GetAll<Country>()
    }
}

Здесь мой метод тестирования

[Fact]
public void ConvertToLocalOrderHeader_GivenConfirmedOrderMessage_CallTheConversionMethods()
{
    // create a partial mock 'cause I want some of the implementation to be the true sut class
    var sut = MockRepository.GeneratePartialMock<OrderMessageHandler>();
    // create a stub for the repository, in order to avoid hitting the db
    sut.Repository = MockRepository.GenerateStub<IRepository>();
    sut.Repository.Stub(r => r.GetAll<Country>())
       .Return(
           new List<Country>
               {
                   new Country {CountryID = "IT", Description = "Italy"},
                   new Country {CountryID = "US", Description = "United States"}
               }.AsQueryable()
    );
    sut.Repository.Stub(r => r.SaveUpdate<OrderHeader>(Arg<OrderHeader>.Is.Anything));

    // call the method I want to test
    sut.Handle(new UpdateOrder
        {
            Order = order,
            EventId = new Guid(),
            EventTime = DateTime.Now
        });

    // verify that the method has been called (this is useless in my real test, I put it here just to understand why it doesn't work)
    sut.AssertWasCalled(s => s.Handle(Arg<UpdateOrder>.Is.Anything));
    // verify that an inner method (virtual) has been called during the execution of sut.handle()
    sut.AssertWasCalled(s => s.ConvertToLocalOrderHeader(order));                    
}

В sut.AssertWasCalled 2 sut.AssertWasCalled я получаю сообщение об ошибке. Ссылка на объект не установлена в экземпляр объекта. , Причина в том, что sut.AssertWasCalled делает вызов метода, который я проверяю... таким образом

sut.AssertWasCalled(s => s.Handle(Arg<UpdateOrder>.Is.Anything));

звонки

sut.Handle(null) 

И имея значение null, метод выдает исключение. Жаль, проблема заключается в том, что он не должен повторно вызвать метод, а просто скажите мне, если он никогда не был вызван ранее в методе тестирования. Что здесь не так?

Редактировать:

согласно предложению, полученному в комментариях, я попробовал другой подход (учитывая, что мне не нравится вкус/подтверждение). Здесь метод тестирования:

[Fact]
public void ConvertToLocalOrderHeader_GivenConfirmedOrderMessage_CallTheConversionMethods2()
{
    var mocks = new MockRepository();
    var sut = mocks.PartialMock<OrderMessageHandler>();
    sut.Repository = mocks.Stub<IRepository>();
    sut.Repository.Stub(r => r.GetAll<Country>())
           .Return(
               new List<Country>
                   {
                       new Country {CountryID = "IT", Description = "Italy"},
                       new Country {CountryID = "US", Description = "United States"}
                   }.AsQueryable()
        );
    sut.Repository.Stub(r => r.SaveUpdate<OrderHeader>(Arg<OrderHeader>.Is.Anything));
    Expect.Call(() => sut.Handle(Arg<UpdateOrder>.Is.Anything));
    sut.Replay();
    sut.Handle(new UpdateOrder
        {
            Order = order,
            EventId = new Guid(),
            EventTime = DateTime.Now
        });
    mocks.VerifyAll();       
}

Здесь ошибка:

System.InvalidOperationException
Previous method 'OrderMessageHandler.get_Repository();' requires a return value or an exception to throw.

Ошибка вызывается строкой кода

Expect.Call(() => sut.Handle(Arg<UpdateOrder>.Is.Anything));

Так что не удачи даже в этом подходе...

Любая другая идея?

  • 0
    Не могли бы вы сделать виртуальный метод Handle? Я думаю, что носорог не может переопределить этот метод в этом случае, если вы не сделаете это.
  • 0
    хм, вы правы ... жаль, ничего не изменилось в общем поведении: у меня все та же проблема
Показать ещё 3 комментария
Теги:
mocking
rhino-mocks

1 ответ

3
Лучший ответ

Я выяснил, в чем проблема: метод ConvertToLocalOrderHeader должен быть объявлен как минимум protected internal, чтобы позволить Rhinomocks отменить его. Virtual недостаточно, будучи классом тестирования другого класса. Очень простое решение проблемы, которая потребовала времени для решения:/

Ещё вопросы

Сообщество Overcoder
Наверх
Меню