如何使用NServiceBus对测试处理程序进行单元测试?

时间:2013-04-29 17:52:38

标签: unit-testing nservicebus

这应该很简单,我可能会遗漏一些东西。我在这里工作:http://support.nservicebus.com/customer/portal/articles/856297-unit-testing

以下内容总是失败:

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

如果我在处理程序中设置断点,则为message.CorrelationId == Guid.Empty。测试期间抛出的异常是:

System.Exception:未实现ExpectedReplyInvocation。 打电话: SendInvocation

我尝试过使用bus.Send,bus.Publish,bus.Reply但每个都失败了相应的Expected * Invocation。

为什么message.CorrelationId == Guid.Empty而不是我提供的值?为什么Test.Handler&lt;&gt;检测到我在处理程序中调用了Send / Reply / Publish?

注意:使用Nuget的NServiceBus 3.3。

2 个答案:

答案 0 :(得分:1)

这里有几个问题。

  1. 在您的处理程序中,您尝试Bus.Send()一个事件(IEventThatHappened实现IEvent,甚至命名为一个事件),这是不允许的。命令已发送,事件已发布。
  2. 您的测试正在使用ExpectReply,如果处理程序正在执行Bus.Reply(),则会出现这种情况。假设您修复了#1,我相信您会寻找.ExpectPublish()
  3. 首先,你需要找出你真正意义上的事情!

答案 1 :(得分:0)

您需要Reply而不是Send

这是通过的测试:

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