c# - 如何使用 NSubstitute 在单元测试中模拟 MassTransit 标头值
问题描述
我正在尝试创建一个单元测试来测试我的 MassTransit (RabbitMq) 消费者。我的消费者需要一个名为UserName
. 我已将我的消费者类简化如下。我需要找到一种方法来模拟总线头数据,否则测试在执行时总是会引发异常context.Headers.TryGetHeader("UserName", out object value)
我正在使用NSubstitute 模拟库。那么如何模拟ConsumeContext<MyDataObject>
类型,并设置模拟头值呢?我更喜欢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 时不要模拟标头值,只需在使用测试工具发送消息时设置它们。对模拟框架的需求绝对为零。
await harness.InputQueueSendEndpoint.Send(mockDataObject,
context => context.Headers.Set(“UserName”, “Bob”));
ConsumeContext
然后,当消息传递给消费者时,标头将可用。
推荐阅读
- hybris - Hybris:是什么导致了几个 Backoffice Long Operation 项目,这似乎导致了性能问题?
- java - 使用 JOLT 解析器无法获得预期的输出
- sql - Teradata 递归更新
- java - ExecutorService 是否消耗线程容量
- asp.net - 在 asp.net vb 中按年和月填充两级树视图
- perl - Net::FTPSSL 在命令通道 [0] (0, 1) () 上给出错误 Unexpected EOF...
- javascript - 使用节点 js 在猫鼬和车把中进行分页
- java - 使用 jsoup 时 Java 运行时环境检测到致命错误
- android - 使用两个两个活动创建 Android PDF 文件
- c - 有没有办法根据命令行参数扩展宏?