如何在没有响应的情况下对 MassTransit 消费者进行单元测试

use*_*039 5 c# unit-testing masstransit azure-servicebus-queues

我想对我的 MassTransit 消费者进行单元测试,该消费者不会发回响应。目前,我的测试似乎确实正在发布消息,但消费者没有被触发,所以我的断点根本没有被击中。

\n

消费者相当简单,但它确实有通过 DI 注入的服务。

\n
public class BudgetExceededConsumer : IConsumer<IBudgetExceeded>\n{\n    private readonly INotificationHubService _notificationHubService;\n\n    public BudgetExceededConsumer(INotificationHubService notificationHubService)\n    {\n        _notificationHubService = notificationHubService;\n    }\n\n    public async Task Consume(ConsumeContext<IBudgetExceeded> context)\n    {\n        try\n        {\n            var message = context.Message;\n\n            await _notificationHubService.SendNotificationAsync(context.Message);\n        }\n        catch (Exception ex)\n        {\n            throw new Exception("Failed to send push notification for exceeding budget usage", ex);\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

使用以下命令将使用者添加到我的 Azure 函数中:

\n
        builder.Services.AddMassTransitForAzureFunctions(cfg =>\n        {\n            cfg.AddConsumersFromNamespaceContaining<ConsumerNamespace>();\n\n        });\n
Run Code Online (Sandbox Code Playgroud)\n

我有一个相对简单的服务,其他功能使用它来发送消息:

\n
    private readonly ISendEndpointProvider _sendEndpoint;\n\n    public MessagingService(ISendEndpointProvider sendEndpoint)\n    {\n        _sendEndpoint = sendEndpoint;\n    }\n\n    public async Task SendMessage<T>(string queueName, object messageBody) where T : class, MessageBase\n    {\n        var endpoint = await _sendEndpoint.GetSendEndpoint(new Uri($"queue:{queueName}"));\n\n        await endpoint.Send<T>(messageBody);\n    }\n
Run Code Online (Sandbox Code Playgroud)\n

我想为消费者编写一个简单的测试,以便我可以模拟该服务,然后验证模拟的服务是否正在被调用。但是,我无法达到运行测试的程度,并且我的消费者被断点击中。\n我没有在 DI 中的任何位置设置注入消费者的服务。目前,它并没有抱怨让我认为我在设置中遗漏了一些东西。

\n
    public async Task Budget_message_gets_consumed()\n    {\n        await using var provider = new ServiceCollection()\n            .AddMassTransitInMemoryTestHarness(cfg =>\n            {\n                cfg.AddConsumer<BudgetExceededConsumer>();\n                cfg.AddConsumerTestHarness<BudgetExceededConsumer>();\n            })\n            .BuildServiceProvider(true);\n\n        var harness = provider.GetRequiredService<InMemoryTestHarness>();\n\n        await harness.Start();\n\n        try\n        {\n            var bus = provider.GetRequiredService<IBus>();\n\n            BudgetExceededMessage message = new BudgetExceededMessage\n            {\n                UserEmailAddress = "test@email.com",\n                Budget = "\xc2\xa320.00",\n                TotalSpend = "\xc2\xa323.56"\n            };\n            await bus.Publish(message);\n\n            var result = await harness.Consumed.Any<IBudgetExceeded>();\n\n            Assert.That(result, Is.True); //This is true\n            \n            var consumerHarness = provider.GetRequiredService<IConsumerTestHarness<BudgetExceededConsumer>>();\n            var result2 = await consumerHarness.Consumed.Any<IBudgetExceeded>();\n            Assert.That(result2, Is.True); //This is FALSE. \n        }\n        finally\n        {\n            await harness.Stop();\n\n            await provider.DisposeAsync();\n        }\n    }\n
Run Code Online (Sandbox Code Playgroud)\n

正如您所看到的,第二个断言是错误的。我想,如果这是真的,那么我就会看到我的消费者受到了打击。

\n

我是否需要更改此处的部分设置,以便正确评估第二个断言?我知道我的设置与文档略有不同,因为我没有使用给出响应的方法。

\n

谢谢

\n

Chr*_*son 0

如果您的使用者具有依赖项,并且该依赖项未在服务集合中配置,则创建使用者时可能会失败。如果您ILoggerFactory使用控制台输出添加到容器,您会在单元测试输出中看到它。

或者使用 MassTransit v8,其新版本的测试工具会自动包含用于测试输出的控制台记录器。