NSubstitute vs PRISM EventAggregator: Assert that calling a method triggers event with correct payload

Viewed 723

Consider the below method that updates a person and publishes an event through the PRISM EventAggregator to indicate that the person has been updated.

I would like to unit test that the message is sent with the correct payload. In this case that would mean the correct personId.

public void UpdatePerson(int personId)
{
    // Do whatever it takes to update the person
    // ...

    // Publish a message indicating that the person has been updated
    _eventAggregator
        .GetEvent<PersonUpdatedEvent>()
        .Publish(new PersonUpdatedEventArgs
        {
            Info = new PersonInfo
            {
                Id = personId,
                UpdatedAt = DateTime.Now
            };
        });
}

I know that I can create a substitute for the event aggregator:

var _eventAggregator = Substitute.For<IEventAggregator>();

However, I don't know how to detect when a message is sent and how to check its payload.

4 Answers

In my opinion, using the real EventAggregator instead of a mock makes the tests much easier to write and read. However, I stumbled over an issue where my tests would sometimes fail if they were ran as part of a test suite:

When subscribing to an event from test code (to assert that the code under test published the event correctly), the following additional parameters need to be provided to the Subscribe method:

event.Subscribe(..., 
                threadOption: ThreadOption.PublisherThread, 
                keepSubscriberReferenceAlive: true)

Otherwise, the test subscription was sometimes not triggered.

The authors of Prism do this in their own tests (https://github.com/PrismLibrary/Prism/blob/master/tests/Prism.Core.Tests/Events/PubSubEventFixture.cs)

Related