MassTransit SagaStateMachine testing shouldn't be this hard, should it?

I'm trying to write unit tests for MassTransit SagaStateMachine.

The SagaStateMachine has some activities associated to it, so I'm having to write a service provider and add it when configuring the receive endpoint.

My issue is when I try to resolve ISagaRepository as InMemorySagaRepository it returns null and hence forth I can't confirm anything actually worked in my mocks.

Is there an easier way to do this? I'm at my wits end.

The activities include a discord socket client which I've mocked and injected in the service provider and you can see my source here: https://github.com/robertkirkham88/NightFuryBot/blob/master/tests/NFB.UI.DiscordBot.Tests/StateMachines/FlightStateMachineTests.cs

Line 146 is where the issue lies but I might be doing something wrong with my setting up the bus. The unit tests on MassTransit and Automatonymous are not helpful and I can't find any other solution on git/stackoverflow.

var repo = this.provider.GetService<ISagaRepository<FlightState>>() as InMemorySagaRepository<FlightState>;
Assert.NotNull(repo);

1 answer

  • answered 2020-09-21 20:10 Chris Patterson

    Version 7.0.4 of MassTransit included container-based configuration for the InMemoryTestHarness, making it easier to configure tests when using a container.

    The Release Notes cover usage, which is also shown below.

    Based on the code you linked, you would need:

    services.AddMassTransitInMemoryTestHarness(cfg =>
    {
        cfg.AddSagaStateMachine<FlightStateMachine, FlightState>()
            .InMemoryRepository();
    
        cfg.AddSagaTestHarness<FlightState>();
    });
    

    And then, once the container is built, you can resolve the test harness and start it.

    var harness = provider.GetRequiredService<InMemoryTestHarness>();
    
    await harness.Start();
    

    The state machine should already be configured on an endpoint, so your Publish calls should deliver events to the state machine.

    Also, you should only need ISagaRepository<T> to check if sagas are present.