Closed rsnj closed 5 years ago
Good question 🤔 let me take a look
I took a look, and I realized that the reason why IFailed<T>
cannot readily be delivered via the saga fixture thing, is that messages delivered this was are actually sent – just like real messages.
In this regard, the saga fixture is very realistic – it is a fully configured Rebus endpoint, only running with the in-mem transport, and some special hooks into the in-mem saga storage.
Simulating a second level retry would require some alternative way of delivering the message.... I will have to think about this some more
I am still thinking... sorry for taking so long 😐
I think faking an IFailed<>
with the saga fixture requires some special tricks.
One way I can think of that might work is to attach a special header to the IFailed<>
message when sending it, which can then be recognized in the incoming messages pipeline in a piece of middleware, which in turn can somehow bring the error tracker into the correct state, faking it as if the message has already had all of its 1st level delivery attempts carried out.
Requires more thinking :) I am changing this issue into a task:
IFailed<>
can be simulated somehow with SagaFixture
Would it be possible to add a method to the SagaFixture to pass the message and Exception to? That method would then be responsible for adding the plumbing to the message to enable it to be delivered as an IFailed message.
Something like that, yes 😄
This may be somewhat related to #663, where I propose an integration testing facility for complex mechanisms like second level retries, deferrals, custom pipeline steps and the like.
Fixed in Rebus.TestHelpers 5.1.0 – now you can
fixture.DeliverFailed(new OrdinaryMessage(...), new ApplicationException("oh no"));
and then the message will be immediately dispatched as an IFailed<OrdinaryMessage>
.
Please note that handling IFailed<T>
has the same requirements as an ordinary message on sagas, so you need to decide whether to IHandleMessages<IFailed<Yourmessage>>
or IAmInitiatedBy<IFailed<Yourmessage>>
.
Moreover, you need to
protected override void CorrelateMessages(ICorrelationConfig<YourSaga> config)
{
config.Correlate<IFailed<Yourmessage>>(m => m.Message.SomeField, d => d.SomethingOnYourSaga);
}
Let me know if it works out 😄
How can you unit test IFailed<> messages from the SagaFixture? I’ve tried creating a MockFailed class that implements IFailed and pass that to the Deliver method of the SagaFixture but it does not get handled by my Saga. The messages are Correlated correctly and they work using the SimpleRetryStrategy, but don’t work with the SagaFixture.