使用 Rebus 对 CorrelationId 进行单元测试

Unit Testing CorrelationId with Rebus

所以假设我有一个看起来像这样的 Handler:

public async Task Handle(Message message)
{
    Guid correlationId = GetCorrelationId();

    var newMessage = new MessageReceived
    {
        horse = message.Horse,
        correlationId = correlationId
    };
}

private static Guid GetCorrelationId()
{
    if (!MessageContext.Current.Headers.TryGetValue("rbs2-corr-id", out string correlationId))
    {
        throw new ArgumentException();
    }

    if (!Guid.TryParse(correlationId, out Guid correlationIdGuid))
    {
        throw new ArgumentException();
    }

    return correlationIdGuid;
}

我将如何进行单元测试?我目前有一个(显然是错误的)测试,我只是设置了一个 MessageReceived 对象并将其传递给 Handle,但是当然它在 GetCorrelationId 失败了,因为没有实际的 MessageContext。我是否必须设置一个 FakeBus 并以某种方式使用它?

与其通过静态 MessageContext.Current 属性 访问当前 IMessageContext,不如像这样将其注入到处理程序的构造函数中:

public class MyHandler : IHandleMessages<Message>
{
    public MyHandler(IMessageContext messageContext)
    {
        this.messageContext = messageContext;
    }

    public async Task Handle(Message message)
    {
        Guid correlationId = GetCorrelationId(messageContext);

        var newMessage = new MessageReceived
        {
            horse = message.Horse,
            correlationId = correlationId
        };
    }

    static Guid GetCorrelationId(IMessageContext messageContext)
    {
        if (!messageContext.Headers.TryGetValue("rbs2-corr-id", out string correlationId))
        {
            throw new ArgumentException();
        }

        if (!Guid.TryParse(correlationId, out Guid correlationIdGuid))
        {
            throw new ArgumentException();
        }

        return correlationIdGuid;
    }
}

这将使您在测试期间轻松实现要注入的假消息上下文:)