0

https://docs.particular.net/nservicebus/testing/ has a very neat example of how to test a simple Saga. Unfortunately it does not explain, how to do the same with a SqlSaga - ie. a Saga with persistence of state to a database.

Given this saga:

public class SomeFancySaga : SqlSaga<MySagaData>,
    IAmStartedByMessages<ImportantCommand>
{
    protected override string CorrelationPropertyName => nameof(Data.MyPrimaryKey);

    protected override void ConfigureMapping(IMessagePropertyMapper mapper)
    {
        mapper.ConfigureMapping<ImportantCommand>(x => x.CommandId);
    }

    public async Task Handle(ImportantCommand command, IMessageHandlerContext context)
    {
        if (Data.State == MyState.ReadyForUse)
            <do some stuff>
    }
    ...
}

If I try to write test-code like the example in the link, I would do something like this:

// arrange
var context = new NServiceBus.Testing.TestableMessageHandlerContext();
var command = ImportantCommand.Create();
var sut = new CreateSomeFancySaga();

// act
sut.Handle(command, context);

// assert
...

The call to sut.Handle() will throw a NullReferenceException, because the Saga property Data has not been initialized.

How do I correctly wireup the saga for testing so that:

  1. Data is initialized
  2. A real database connection is not really needed
Carsten Gehling
  • 1,218
  • 1
  • 13
  • 31
  • Problem 1 can be solved by initialising SUT as **var sut = new CreateSomeFancySaga() { Data = new MySagaData() }** - but I am not sure if it helps with problem 2. – Carsten Gehling Jun 15 '18 at 11:41
  • Problem 2 is actually moot, as the Handle method is tested isolated. This means that nothing calls the persistence logic. – Carsten Gehling Jun 18 '18 at 07:45

1 Answers1

2

We have a related code sample showing unit testing in more detail: https://docs.particular.net/samples/unit-testing/. That includes a couple of tests for saga (SagaTests.cs).

You can take this as a starting point and modify the saga tests in the following way:

  1. Add NServiceBus.Persistence.Sql package.
  2. Modify the DiscountPolicy policy saga to inherit from SqlSaga instead of a Saga.
  3. Resolve compilation errors (add missing method and property, you can keep them empty, plus remove the ConfigureHowToFindSaga method).

I hope that helps, but let me know if there's anything missing or your scenario can't be tested this way.

wlabaj
  • 468
  • 2
  • 6
  • That was also the solution I got to, as stated in the comment to my OP. I think that I was too absorbed with the fact, that I was testing something with built-in SQL persistance, when in fact I wasn't: I am only testing the Handle() method fully isolated. So it didn't really matter that it was SqlSaga - except for the need to Add NServiceBus.Persistence.Sql package. Maybe you could add that piece of info to your docs - it would be very useful. – Carsten Gehling Jun 18 '18 at 07:42