首页 > 解决方案 > 如何对 Rebus 处理程序 IFailed 进行单元测试启用 secondLevelRetriesEnabled 时的句柄

问题描述

我正在为我的 Rebus 处理程序编写一些单元测试。我已选择启用在处理程序中引发异常时导致发布的secondLevelRetriesEnabled结果。IFailed<TMessage>

我的处理程序类定义是:

Handler<T> : IHandleMessages<T>, IHandleMessages<IFailed<T>>

当我运行该过程时,一切都按预期工作;当尝试为secondLevelRetriesEnabled行为编写单元测试时,困难就来了。

当我的单元测试调用IFailed<TMessage>我的 Handler 的方法导致调用时,await bus.Advanced.TransportMessage.Deadletter(message)我从FakeBus.

"Attempted to dead-letter the current message using error details 'Failed to handle message after 2 deferrals', but no message context could be found! This is probably a sign that this method was called OUTSIDE of a Rebus handler, or on a separate, disconnected thread somehow. Please only call this method inside Rebus handlers."

在测试 IFailed 消息句柄时,有人能指出我解决死信队列异常的正确方向吗?据我所知,没有HandleFixture哪个SagaFixture支持fixture.DeliverFailed(new OrdinaryMessage(...), new ApplicationException("oh no"));

标签: rebus

解决方案


我认为目前还没有一种非常优雅的方式,但是你可以总结并让自己变得漂亮的一种方式是做这样的事情:

// this is the message we're pretending to be handling
var transportMessage = new TransportMessage(...);

using var scope = new RebusTransactionScope();

var transactionContext = scope.TransactionContext;
var incomingStepContext = new IncomingStepContext(transportMessage, transactionContext);

// fake incoming step context here:
transactionContext.Items[StepContext.StepContextKey] = incomingStepContext;

// now MessageContext.Current should return a proper IMessageContext

//< exercise your handler here

//< check incomingStepContext here

这显然是可以更好的,所以请随意在Rebus.TestHelpers 存储库中提出问题,这将是解决该问题的某种解决方案的正确地方。


推荐阅读