NserviceBus.Testing not using ISagaFinder for saga

I have a saga that I am trying to write scenario tests for, and one type of message requires a custom finder. The finder is being called when running the saga normally but if I send that type of message to the TestableSaga from NServiceBus.Testing there is a fault and no saga is found.

We are using NHibernate for our normal Saga persistence, but I am not sure if that affects the testing in any way.

var ackResult = testableSaga.Handle(new Z3Messages.SmartphonePush.AckMessage()
{
    RecipientID = "11"
});

In this instance ackResult will have the status of faulted and I can confirm that the ISagaFinder is not being called. Here is my saga finder.

public class PushSagaFinder : ISagaFinder<PushSagaData, AckMessage>
{
    public Task<PushSagaData> FindBy(AckMessage message, ISynchronizedStorageSession storageSession, IReadOnlyContextBag context, CancellationToken cancellationToken = default)
    {
        var session = storageSession.Session();
        var orderSagaData = session.QueryOver<PushSagaData>()
            .Where(d => d.LastRecipientID == message.RecipientID)
            .SingleOrDefault();
        return Task.FromResult(orderSagaData);
    }
}

Is there some additional setup that needs to be done to get the tests to use the saga finder?

The testable saga is designed for unit testing, not integration testing. It’s all in memory, which is why saga finders are not invoked.

You should be able to unit-test sagas and saga finders in isolation. What’s leading you to need to test them together?

I do have another question, what’s the business scenario that requires saga finders in your case?

I am not trying to test the saga finder in this scenario, I am trying to test the handler for the message type that is handled by the finder. So when I call this

 var ackResult = testableSaga.Handle(new Z3Messages.SmartphonePush.AckMessage()
 {
     RecipientID = "11"
 });

It returns a fault in the ackResult and doesn’t actually call the handler for AckMessage in the saga. The reason for the finder is because the AckMessage uses a different property of the saga data to match on than the rest of the messages the saga handles. If I try to setup the mapper that way it throws an exception on startup that there are multiple properties matched in the mapper.

I guess the real question should be, how do I get the testable saga to call the handler for a message type that uses an ISagaFinder?

@jupham,

Now I understand what the culprit is. I reproduced the problem and raised a spike PR with a potential solution: [Spike] When using saga finders the testable saga fails by mauroservienti · Pull Request #651 · Particular/NServiceBus.Testing · GitHub

At the moment, it’s a spike. I haven’t investigated the ramifications and I dislike the test fake finders requirements. It should provide a better API.

@mauroservienti

Just confirming, I see the referenced PR has been abandoned. Is there any movement on this? Or is this just currently an unsupported test scenario?

Thanks,
Max Schilling

I’m upgrading some old projects who were still on NServicebus 6. These projects contained extension methods that allowed you to mock a SagaFinder when using the (now deprecated) Test.Saga of NServicebus.Testing.

In NServicebus 8 we are supposed to test our Saga’s with TestableSaga but evidently this does not supporting injecting/mocking a SagaFinder which results in an error when creating the TestableSaga.

The PR mentioned here would solve this problem. Are there any updates on this?

Sorry for this very late response, @schilm.

What I opened the PR I assumed it could have been a sort of low hanging fruit. It turns out it’s way more complex than originally forecasted. That’s the reason the PR is now closed.

Unfortunately, we don’t have an ETA about when we’ll work on that again.

Thanks for the update.

Just to clarify, based on the information provided, does this mean that if a saga relies on ISagaFinder, it would no longer be compatible with testing via NServicebus.Testing’s TestableSaga? If that’s the case, isn’t this a bit of a breaking change? Our tests are currently broken, and unless we go through a major rewrite, there’s no clear path to fix them.

Would you be able to share any guidance on how to proceed, or if there are any plans to address this in a future release? It would be great to understand what options we have moving forward, especially as we’re facing this issue in multiple projects.

Hey @JanVos-IS,

What you’re talking about was the fluent-style API, which was deprecated in NServiceBus 7.3 and then, because that was a breaking change, removed in NServiceBus 8.0, and was included in the upgrade guide.

However, the successor to those style of tests are the Arrange-Act-Assert style handler tests (not TestableSaga) which do not require saga finders because that style test does not invoke the saga infrastructure at all. You supply all the preconditions of the saga infrastructure when you directly invoke your saga method (the saga data being included in those preconditions) and make assertions on the results.

The scenario testing framework that includes TestableSaga is a completely new/different way to test sagas, which allows for a lot of flexibility and expressive multi-step tests, but doesn’t support saga finders.