Search code examples
masstransitautomatonymous

Test MassTransit state machine saga activity


I'm trying to do unit tests on a custom Activity that I have for my MassTransit state machine saga.

It looks something like this:

public class UpdateActivity : Activity<UpdateState>
{
    private readonly ConsumeContext _consumeContext;
    private readonly ILogger<UpdateActivity> _logger;

    public UpdateActivity(
        ConsumeContext consumeContext,
        ILogger<UpdateActivity> logger
    )
    {
        _consumeContext = consumeContext;
        _logger = logger;
    }

    public void Probe(ProbeContext context) => context.CreateScope(nameof(UpdateActivity));

    public void Accept(StateMachineVisitor visitor) => visitor.Visit(this);

    public async Task Execute(BehaviorContext<UpdateState> context, Behavior<UpdateState> next)
    {
        await DoStuffAsync(context.Instance);
        await next.Execute(context).ConfigureAwait(false);
    }

    public async Task Execute<T>(BehaviorContext<UpdateState, T> context, Behavior<UpdateState, T> next)
    {
        await DoStuffAsync(context.Instance);
        await next.Execute(context).ConfigureAwait(false);
    }

    public Task Faulted<TException>(BehaviorExceptionContext<UpdateState, TException> context, Behavior<UpdateState> next) where TException : Exception
        => next.Faulted(context);

    public Task Faulted<T, TException>(BehaviorExceptionContext<UpdateState, T, TException> context, Behavior<UpdateState, T> next) where TException : Exception
        => next.Faulted(context);
}

What I can't figure out is how I can mock/fake expectations for the ConsumeContext when writing unit tests for this class. I've tried to find something using the InMemoryTestHarness but can't find anything suitable.

EDIT:

I might as well throw this one as well in there. How do I mock context or run this in a test harness? So that I can unit test this Activity as well?

    public class UpdateActivity : Activity<UpdateState, IDataUpdatedEvent>
    {
        private readonly ILogger<UpdateActivity> _logger;

        public UpdateActivity(
            ILogger<UpdateActivity > logger
        )
        {
            _logger = logger;
        }

        public void Probe(ProbeContext context) => context.CreateScope(nameof(UpdateActivity));

        public void Accept(StateMachineVisitor visitor) => visitor.Visit(this);

        public async Task Execute(BehaviorContext<UpdateState, IDataUpdatedEvent> context, Behavior<UpdateState, IDataUpdatedEvent> next)
        {

Solution

  • MassTransit has test harnesses to allow state machines to be tested, along with activities using Dependency Injection.

    The idea of "testing in isolation with mocks" is fairly pointless given the availability of these harnesses.