c# - MassTransit - Unit Testing a Large Payload Consumer
问题描述
Using the InMemoryTestHarness, I am working on unit testing a Consumer that handles a command with a MessageData property. Using the InMemoryMessageDataRepository to populate the MessageData property works fine however, when the consumer attempts to load the payload (message.Body.Value) I am receiving the following exception: "The message data was not loaded: urn:msgdata:xxxxxxxxxxxxxxxxxxxxxxxxxx"}. What is the proper way to unit test a consumer that handles commands with a MessageData property?
I was going to use the In-memory transport, but it doesn't seem like the right approach since the unit test(s) will not receive immediate feedback from the consumer. Ultimately the end goal is for my unit tests to be able assert that specific exceptions are thrown or that the consumer completed successfully without errors.
using System;
using System.Linq;
using System.Threading.Tasks;
using MassTransit;
using MassTransit.MessageData;
using MassTransit.Testing;
using Newtonsoft.Json;
using Xunit;
namespace Test
{
public class LargePayloadConsumerTest
{
[Fact]
public async Task Consumer_Should_Deserialize_Message()
{
var harness = new InMemoryTestHarness();
var consumer = harness.Consumer<BigMessageConsumer>();
var command = new BigMessageCommand();
var dataRepo = new InMemoryMessageDataRepository();
var largePayload = new BigMessagePayload()
{
Id = 1,
FirstName = "TestFirstName",
MiddleName = "TestMiddleName",
LastName = "TestLastName"
};
var json = JsonConvert.SerializeObject(largePayload);
command.Body = await dataRepo.PutString(json);
var thisWorks = await command.Body.Value;
await harness.Start();
await harness.InputQueueSendEndpoint.Send(command);
Assert.True(harness.Consumed.Select<BigMessageCommand>().Any());
}
public class BigMessageConsumer : IConsumer<BigMessageCommand>
{
public async Task Consume(ConsumeContext<BigMessageCommand> context)
{
try
{
var json = await context.Message.Body.Value;
var deserialized = JsonConvert.DeserializeObject<BigMessagePayload>(json);
Console.WriteLine($"{deserialized.Id}: {deserialized.FirstName} {deserialized.MiddleName} {deserialized.LastName}");
}
catch (Exception e)
{
//throws {"The message data was not loaded: urn:msgdata:xxxxxxxxxxxxxxxxxxxxxxxxxx"}
Console.WriteLine(e);
throw;
}
}
}
public class BigMessageCommand
{
public MessageData<string> Body { get; set; }
}
public class BigMessagePayload
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string MiddleName { get; set; }
}
}
}
解决方案
您需要配置接收端点来处理消息数据属性,类似于:
e.UseMessageData<BigMessageCommand>(dataRepo);
由于您使用的是测试工具,因此您可以在添加消费者测试工具之前将其添加到接收端点:
void ConfigureReceiveEndpoint(IReceiveEndpointConfigurator configurator)
{
configurator.UseMessageData<BigMessageCommand>(dataRepo);
}
harness.OnConfigureReceiveEndpoint += ConfigureReceiveEndpoint;
推荐阅读
- php - 在 WooCommerce 预订中用于取消预订的挂钩是什么?
- python - Scipy 最小化具有多个约束
- r - 当特定列相等时所有行的总和-R中的-data.frame
- c++ - 把课堂传进课堂
- reactjs - 在 React 测试站点上阻止 Chrome 自动填充电子邮件/密码?
- websocket - 与 websockets 握手时连接关闭
- flutter - Flutter 无法在父 ListView 中实现类似 Swipeable Tabs 的 PageView
- python - 将代码和打印结果合并到 excel .csv 文件中
- excel - 来自另一个工作簿的 excel 加载项 .xla 参考
- javascript - 您在 Redux Observable 中预期流的位置提供了 `undefined`