0
votes

This should be simple and I'm probably missing something. I'm working from here: http://support.nservicebus.com/customer/portal/articles/856297-unit-testing

The following always fails:

[TestFixture]
public class MyTestFixture
{
    [Test]
    public void RoundTrip() {
        Test.Initialize();

        var correlationId = Guid.NewGuid();
        Test.Handler(bus => new MyHandler(bus))
            .ExpectReply<IEventThatHappened>(m => m.CorrelationId == correlationId)
            .OnMessage<MyCommand>(m => new MyCommand(correlationId));
    }

}

public interface IEventThatHappened : IEvent
{
    Guid CorrelationId { get; set; }
}

public class MyCommand : ICommand
{
    public Guid CorrelationId { get; private set; }

    public MyCommand(Guid correlationId) {
        CorrelationId = correlationId;
    }
}

public class MyHandler : IHandleMessages<MyCommand>
{
    private readonly IBus _bus;

    public MyHandler(IBus bus) {
        if (bus == null) {
            throw new ArgumentNullException("bus");
        }
        _bus = bus;
    }

    public void Handle(MyCommand message) {
        _bus.Send<IEventThatHappened>(m => m.CorrelationId = message.CorrelationId);
    }
}

If I set a breakpoint inside my handler, the message.CorrelationId == Guid.Empty. The exception thrown during the test is:

System.Exception : ExpectedReplyInvocation not fulfilled. Calls made: SendInvocation

I've tried using bus.Send, bus.Publish, bus.Reply but each one fails with the corresponding Expected*Invocation .

Why is the message.CorrelationId == Guid.Empty instead of the value I supplied? Why doesn't Test.Handler<> detect that I've called Send/Reply/Publish in my handler?

NOTE: Using NServiceBus 3.3 from Nuget.

2

2 Answers

1
votes

There are a couple issues here.

  1. In your handler, you are trying to Bus.Send() an event (the IEventThatHappened implements IEvent and is even named like an event), which is not allowed. Commands are Sent, Events are Published.
  2. Your test is using ExpectReply, which is what you would expect if the handler were doing Bus.Reply(). Assuming you fixed #1, I believe you would be looking for .ExpectPublish().

So first you need to work out what it really is you're meaning to do!

0
votes

You need to Reply instead of Send!

Here is the test that passes:

[TestFixture]
public class MyTestFixture
{
    [Test]
    public void RoundTrip()
    {
        Test.Initialize();

        var correlationId = Guid.NewGuid();
        var myCommand = new MyCommand(correlationId);

        Test.Handler(bus => new MyHandler(bus))
            .ExpectReply<IEventThatHappened>(m => m.CorrelationId == correlationId)
            .OnMessage(myCommand);
    }

}

public interface IEventThatHappened : IEvent
{
    Guid CorrelationId { get; set; }
}

public class MyCommand : ICommand
{
    public Guid CorrelationId { get; private set; }

    public MyCommand(Guid correlationId)
    {
        CorrelationId = correlationId;
    }
}

public class MyHandler : IHandleMessages<MyCommand>
{
    private readonly IBus _bus;

    public MyHandler(IBus bus)
    {
        if (bus == null)
        {
            throw new ArgumentNullException("bus");
        }
        _bus = bus;
    }

    public void Handle(MyCommand message)
    {
        _bus.Reply<IEventThatHappened>(m => m.CorrelationId = message.CorrelationId);
    }
}