FakeMessageContext генерирует исключение NullReferenceException

Я пытаюсь написать модульный тест для своей саги. Я использовал SagaFixture для размещения своей Saga и использования FakeBus. Я также использовал FakeMessageContext, потому что в исполнении Saga я использую MessageContext для получения обратного адреса.

Теперь, когда я пытаюсь вызвать метод Handle для Fixture, он выдает исключение типа NullReferenceException.

Вставка кода ниже:

ПоискSaga

public class SearchSaga : Saga<SearchSagaData>, IAmInitiatedBy<PersonRequested>, IHandleMessages<PersonSearchCompleted>
{
    public void Handle(PersonRequested message)
       {
            Data.Id = new Guid(message.MessageId);
            Data.ReturnAddress = MessageContext.GetCurrent().ReturnAddress;
            Bus.Publish(message);
        }

}

СагаЮнитТест

[Test]
        public void PublishResponseOfTypeSearchPersonRequest()
        {
            var bus = new FakeBus();
            var saga = new SearchSaga(bus);
            var fixture = new SagaFixture<SearchSagaData>(saga);
            FakeMessageContext.Reset();
            var fakeContext = MockRepository.GenerateMock<IMessageContext>();
            fakeContext.Stub(s => s.ReturnAddress).Return("queuename");
            fakeContext.Stub(s => s.Headers).Return(new Dictionary<string, object>());

            // act
            using (FakeMessageContext.Establish(fakeContext))
            {
                fixture.Handle(new PersonRequested {MessageId = Guid.NewGuid().ToString(), Query = "Abc"});
            }
            var sentRequests = bus.PublishedMessages.OfType<SearchPersonRequest>().ToList();
            Assert.That(sentRequests.Count, Is.EqualTo(1));
        }

Трассировка стека ошибок: в Rebus.SagaContext..ctor(идентификатор GUID) в Rebus.Bus.Dispatcher.DispatchToHandler[TMessage](сообщение TMessage, IHandleMessages1 handler) at Rebus.Testing.SagaFixture1.Handle[TMessage](сообщение TMessage)


person priyank brahmbhatt    schedule 10.09.2013    source источник


Ответы (1)


Исключение вызвано тем фактом, что ваш макет IMessageContext имеет значение null в свойстве Items. Выброшенное исключение просто довольно плохо, но я позабочусь о том, чтобы в будущем сообщаемая ошибка исправилась.

На данный момент вы можете исправить ситуацию, настроив словарь элементов следующим образом:

fakeContext.Stub(s => s.Items).Return(new Dictionary<string, object>());

Более того, вместо того, чтобы использовать MessageContext.GetCurrent() для доступа к контексту сообщения внутри вашего обработчика, вы должны воспользоваться тем фактом, что все адаптеры контейнеров Rebus IoC гарантируют, что вы можете внедрить IMessageContext во все экземпляры вашего обработчика.

Таким образом, нет необходимости использовать FakeMessageContext в ваших модульных тестах.

person mookid8000    schedule 10.09.2013
comment
Последовал вашему предложению и попал в следующий вопрос. У меня есть Bus.Publish в моей саге, и в этот момент он выдает следующее исключение: System.InvalidCastException: невозможно преобразовать объект типа «Castle.Proxies.IMessageContextProxy9e54bc5d128e47338ab8b9cdfaabd032» в тип «Rebus.MessageContext». в Rebus.MessageContext.get_MessageDispatchAborted() в Rebus.Bus.Dispatcher.Dispatch (сообщение TMessage) в Rebus.Testing.SagaFixture`1.Handle (сообщение TMessage) - person priyank brahmbhatt; 11.09.2013
comment
Ах да, я вижу - кажется, я не предвидел, что FakeMessageContext можно использовать вокруг обработчика сообщений. Я отредактировал свой ответ, указав способ обойти это. - person mookid8000; 11.09.2013
comment
не слишком уверен в правильности моего кода, хотя он работал. нужны ваши взгляды. Не уверен насчет кода в конструкторе по умолчанию private readonly IBus _bus; private readonly IMessageContext _messageContext; public IBus Bus { get { return _bus; } } public SearchSaga() { _bus = RebusHost.Adapter.Bus; _messageContext = MessageContext.GetCurrent(); } public SearchSaga(IBus bus, IMessageContext messageContext) { _bus = bus; _messageContext = messageContext; } - person priyank brahmbhatt; 12.09.2013