1

I want to unit test a module by throwing messages at it via Event Aggregation to make sure it responds appropriately, either by setting properties appropriately, or by publishing other messages as a result. I am using Prism 6. In my project, the infrastructure project has:

 public class ImportantMessage : PubSubEvent<string>
 {
 }

ModuleA publishes a message like this:

eventAggregator.GetEvent<ImportantMessage>().Publish(importantString);

ModuleB receives the message like this:

eventAggregator.GetEvent<ImportantMessage>().Subscribe(HandleImportantMessage);

Here is HandleImportantMessage:

public void HandleImportantMessage(string importantString)
{
   . . .
}

The ModuleB constructor is called as follows:

ModuleB(IEventAggregator EventAggregator)

This constructor is called by the Prism framework. For unit testing, I need to create an instance of ModuleB, and pass an IEventAggregator, probably a fake one created by Moq. And I want to do this in such a way that the message I publish carries importantString with it. If I Google the phrase “unit tests with moq and event aggregation,” there are several references, but I didn’t see how to use any of these approaches to pass “importantString” from ModuleA To ModuleB. The sample code for Prism 5 creates a fake event aggregator, but without using Moq. I don't understand how it works, and don't see how to pass a string with it.

My test code starts off something like this:

var moqEventAggregator = new Mock(IEventAggregator);
var moqImportantMessage = new Mock<ImportantMessage>();
moqEventAggregator.Setup(x => x.GetEvent<ImportantMessage>());

Some of the references I have seen apply something like .Returns(eventBeingListenedTo.Object); to moqEventAggregator after Setup is applied. I obviously need to apply .Setup(something) to moqImportantMessage in order to pass importantString, but I don't see exactly what yet.

What am I missing? How do I pass a string with the fake published message?

  • not exactly a duplicate, but you probably can transfer this from NSubstitute to Moq: http://stackoverflow.com/questions/35868184/nsubstitute-vs-prism-eventaggregator-assert-that-calling-a-method-triggers-even/35889556#35889556 – Haukinger Mar 22 '16 at 07:44

1 Answers1

0

Basically you need to mock 2 things here:

  1. The event aggregator
  2. The event itself

Given you have the mock of the event you need to do as you said:

moqEventAggregator.Setup(x => x.GetEvent<ImportantMessage>()).Returns(moqImportantMessage);

Mocking the event itself should be like so:

Action<string> action;
moqImportantMessage.Setup(_ => _.Subscribe(It.IsAny<Action<string>>>()))
    .Callback(_action => 
    {
        action = _action;
    });

And then you can raise the subscription like so:

action("some string");
Slava Shpitalny
  • 3,965
  • 2
  • 15
  • 22
  • I'm still trying to make this suggestion work (after cleaning up syntax). I get an error "System.NotSupportedException: Invalid setup on a non-virtual (overridable in VB) member". I'm trying to find out how to get around it. – user3777273 Mar 22 '16 at 19:57
  • yes sorry I forgot you can mock only virtual methods...Did you try returning the real event and not a mock? – Slava Shpitalny Mar 22 '16 at 20:11