我正在尝试创建一个单元测试来测试我的 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();
}
}
}
答案 0 :(得分:0)
在使用 MassTransit 时不必模拟标头值,只需在使用测试工具发送消息时设置它们即可。对模拟框架的需求绝对零。
function getProducts() {
http
.get(url, (res) => {
let body = "";
res.on("data", (chunk) => {
body += chunk;
});
res.on("end", () => {
try {
let json = JSON.parse(body);
console.log(json);
} catch (error) {
console.error(error.message);
}
});
})
.on("error", (error) => {
console.error(error.message);
});
}
当消息传递给消费者时,标头将在 await harness.InputQueueSendEndpoint.Send(mockDataObject,
context => context.Headers.Set(“UserName”, “Bob”));
上可用。