Search code examples
rebus

Testing sagas dependent on IBus using SagaFixture


What approach should I take if I want to test a saga using

 using(var fixture = SagaFixture.For<CollectLegalInfoSaga>())
    {
        // perform test in here
    }

The saga relies on an IBus instance beeing injected (either constructor or property. If the Bus property is null, one or more handlers in the saga will fail.

public class CollectLegalInfoSaga : Saga<CollectLegalInfoSagaData>,
      IAmInitiatedBy<CustomerCreated>,
      IHandleMessages<LegalInfoAcquiredInFirstSystem>,
      IHandleMessages<LegalInfoAcquiredInSecondSystem>
    {
        public IBus Bus {get;set;}

    }

As far as I can see the SagaFixture wrapps the _activator which holds reference to an instance of a IBus.


Solution

  • I suggest you do something like this:

    // this one implements IBus
    var fakeBus = new FakeBus();
    
    using(var fixture = SagaFixture.For(() => new CollectLegalInfoSaga(fakeBus)))
    {
        // dispatch message(s) to saga here by calling
        // fixture.Deliver(message);
        // 
        // (....)
        //
        // assert that certain things have happened
        var sentRequests = fakeBus.Events
            .OfType<MessageSent<GetLegaInfoRequest>>()
            .ToList();
    
        Assert.That(sentRequests.Count, Is.EqualTo(1));
    
        var actualRequest = sentRequests.Single().CommandMessage;
    
        Assert.That(request.LegalEntityId, Is.EqualTo("wwwwhatever"));
    }
    

    That is,

    1. Create FakeBus which is an IBus implementation that collects FakeBusEvents in the form of MessageSent<TCommandMessage>, MessagePublished<TEventMessage>, etc.
    2. Pass factory method to SagaFixture and inject your FakeBus instance
    3. Check that the expected things were done to the FakeBus

    The IBus instance within SagaFixture is not accessible because it is only used in order to provide the most realistic environment for passing messages to your saga – in fact, it IS a fully functioning bus instance that just happens to run on in-mem implementations of transport, saga persister, etc.