繁体   English   中英

如何使用 NSubstitute 在单元测试中模拟 MassTransit Header 值

[英]How to mock MassTransit Header values in unit test using NSubstitute

我正在尝试创建一个单元测试来测试我的 MassTransit (RabbitMq) 消费者。 我的消费者需要一个名为UserName的总线 header 键。 我已将我的消费者 class 简化如下。 我需要找到一种方法来模拟总线 header 数据,否则测试在执行context.Headers.TryGetHeader("UserName", out object value)时总是会引发异常

我正在使用NSubstitute mocking 库。 那么如何模拟ConsumeContext<MyDataObject>类型,并设置模拟 header 值? 我更喜欢NSubstitute的解决方案

public class MyDataObjectCommand
{
    public string MyProperty { get; set; }
}

// Consumer class
public class MyConsumer : IConsumer<MyDataObjectCommand>
{
    private readonly IHubContext<MessageHub> _hubContext;

    public MyConsumer(IHubContext<MessageHub> hubContext)
    {
        _hubContext = hubContext;
    }

    public async Task Consume(ConsumeContext<MyDataObjectCommand> context)
    {
        var myProperty = context.Message.MyProperty;
        var userName = TryGetHeader(context, "UserName");
        DoSomethingWith(_hubContext, myProperty, userName);
    }

    private string TryGetHeader(ConsumeContext<MyDataObjectCommand> context, string key, bool errorOnNull = true)
    {
        if (context.Headers.TryGetHeader(key, out object value))
        {
            return Convert.ToString(value);
        }

        if (errorOnNull)
        {
            throw new MyConsumerException(_reportName, $"{key} is not found", _hubContext);
        }

        return null;
    }
}


// Unit Test (I'm using XUnit)
public class MyConsumerTests
{
    private readonly IHubContext<MessageHub> _hubContext;

    public MyConsumerTests()
    {
       _hubContext = Substitute.For<IHubContext<MessageHub>>();
    }

    [Fact]
    public async Task ShouldConsume()
    {
        // arrange
        var mockDataObject = new MyDataObjectCommand() { MyProperty = "x" };

        var harness = new InMemoryTestHarness();
        harness.Consumer(() => new MyConsumer(_hubContext));

        // I need to mock header values on ConsumeContext<MyDataObjectCommand> object here
        // but how do I do it using NSubstitute?
        // context.Headers["UserName"] = "Bob";  ??

        await harness.Start();
        try
        {
            
            // act
            await harness.InputQueueSendEndpoint.Send(mockDataObject);

            // assert
            Assert.True(await harness.Consumed.Any<MyDataObjectCommand>());
            Assert.False(await harness.Consumed.Any<Fault<MyDataObjectCommand>>());
            //Assert.Equal(context.Header["UserName"], "Bob"); How do I do the assertion??
        }
        finally
        {
            await harness.Stop();
        }
    }
}

使用 MassTransit 时不要模拟header 值,只需在使用测试工具发送消息时设置它们。 对 mocking 框架的需求绝对为零

await harness.InputQueueSendEndpoint.Send(mockDataObject, 
    context => context.Headers.Set(“UserName”, “Bob”));

当消息传递给消费者时,header 将在ConsumeContext上可用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM