Testing the saga

32 views
Skip to first unread message

Wallonman

unread,
May 7, 2020, 8:43:01 AM5/7/20
to masstransit-discuss
Hello,

I'm discovering the saga testing using the InMemoryTestHarness, so the answer to my question is probably obvious :-)


The problem is that the "harness.Consumed" and the "sagaHarness.Consumed" are never populated
// did the endpoint consume the message
Assert.IsTrue(harness.Consumed.Select<InitialEvent>().Any()); // harness.Consumed is empty !!!!!!!!!!


It sounds logic as there is no consumer configured ?!?

In the production code we'll generally declare the saga as an endpoint like this:
cfg.ReceiveEndpoint("MyStateMachineQueue", e =>
            {
                e.StateMachineSaga(machine, repository);

                ....
            });

But how is that done for InMemoryTestHarness ?


Chris Patterson

unread,
May 7, 2020, 11:55:18 AM5/7/20
to masstrans...@googlegroups.com

--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/masstransit-discuss/58d11d2b-9ba2-40e7-8207-21cedebae3f8%40googlegroups.com.

Eric Piraux

unread,
May 8, 2020, 3:03:49 AM5/8/20
to masstrans...@googlegroups.com
Thank you. It is weird, it works when using harness.Bus.Publish<>() but not when using harness.InputQueueSendEndpoint.Send<>()
How is the consumption registration done in the InMemoryTestHarness ?

____________________
Eric Piraux
+32 476 20 29 60


Wallonman

unread,
May 8, 2020, 5:01:42 AM5/8/20
to masstransit-discuss
Hello,

Debugging a bit into the code, I found that the collection returned by sagaHarness.Consumed is populated in a "synchronous way", is that correct ?

Can you explain that :
        public async Task Should_test_the_state_machine_saga()
        {
            var machine = new MyStateMachine();

            var harness = new InMemoryTestHarness();
            var sagaHarness = harness.StateMachineSaga<MyInstance, MyStateMachine>(machine);

            await harness.Start();
            try
            {
                Guid sagaId = NewId.NextGuid();

                await harness.Bus.Publish(new InitialEventImpl(sagaId));

                var test = sagaHarness.Consumed.ToList(); // EMPTY !!!!

                // did the endpoint consume the message
                Assert.IsTrue(harness.Consumed.Select<InitialEvent>().Any());

                test = sagaHarness.Consumed.ToList(); // contains 1 Message

                // did the actual consumer consume the message
                Assert.IsTrue(sagaHarness.Consumed.Select<InitialEvent>().Any());


                /*MyInstance instance = sagaHarness.Created.ContainsInState(sagaId, machine, machine.Active);
                Assert.IsNotNull(instance, "Saga instance not found");*/
            }
            finally
            {
                await harness.Stop();
            }
        }


Chris Patterson

unread,
May 9, 2020, 9:14:37 AM5/9/20
to masstrans...@googlegroups.com
MassTransit is asynchronous, and the call using Select<T> is required to wait for the message to be dispatched to the saga and reported. You shouldn't be using ToList() or Count() or any of those methods.

--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.

Wallonman

unread,
May 12, 2020, 3:14:43 AM5/12/20
to masstransit-discuss
Asynchronous is what's making hard to unit test as you don't exactly know when things happen!

Anyway, thank you pointing that, it helped me to better understand the testing framework.
From the documentation, does my comment make sense ?
public async Task Should_test_the_state_machine_saga()
{
   
var machine = new MyStateMachine();

   
var harness = new InMemoryTestHarness();
   
var sagaHarness = harness.StateMachineSaga<MyInstance, MyStateMachine>(machine);

   
await harness.Start();
   
try
   
{
       
Guid sagaId = NewId.NextGuid();


       
await harness.Bus.Publish(new InitialEvent(sagaId));


       
// did the endpoint consume the message
       
Assert.IsTrue(harness.Consumed.Select<InitialEvent>().Any())
; 
       
/* This is important : it not only verifies the assertion,
         * but behind the scene it waits until the messages are consumed, this is mandatory to let the saga complete its way
         */



       
// did the actual consumer consume the message
       
Assert.IsTrue(sagaHarness.Consumed.Select<InitialEvent>().Any());


       
MyInstance instance = sagaHarness.Created.ContainsInState(sagaId, machine, machine.Active);

       
Assert.IsNotNull(instance, "Saga instance not found");
   
}

   
finally
   
{
       
await harness.Stop();
   
}



I'd suggest to pinpoint that important issue into the documentation (https://masstransit-project.com/usage/testing.html#state-machine-saga), would you like me to suggest a change in the doc ?

Chris Patterson

unread,
May 12, 2020, 10:33:03 AM5/12/20
to masstrans...@googlegroups.com
Yes, that's exactly what is happening.

--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages