---
title: Using Moq for Unit Testing with Prism EventAggregator | ArcTouch
description: "ArcTouch's Xamarin development team explains how to use Moq for unit testing Prism EventAggregator in .NET app development."
url: "https://arctouch.com/blog/moq-unit-testing-prism-eventaggregator"
date_modified: "2025-04-10T19:21:38.495Z"
---
# Using Moq for unit testing with Prism EventAggregator

ArcTouch's Xamarin development team explains how to use Moq for unit testing Prism EventAggregator in .NET app development.

5 min. read - April 8, 2020

By Kristof Bergé

[](mailto:?subject=Interesting%20blog%20post&body=I%20thought%20you%20might%20like%20this%20blog%20post%20from%20ArcTouch%3A%20https%3A%2F%2Farctouch.com%2Fblog%2Fmoq-unit-testing-prism-eventaggregator)

![screen of Moq unit tests prism eventaggregator](/_next/image?url=https%3A%2F%2Fimages.ctfassets.net%2Fefnbmai9c55m%2F7rfKkwAs8k74i2qSlo4DYw%2Fddc58f89239f5a2f9aaa2bfffa544bf3%2Funit-tests-prism-eventaggregator-moq&w=3840&q=75)

_\[Editor’s note: This article assumes basic knowledge of unit testing, Moq, and Prism EventAggregator\]_

Welcome to the third and final post of our [series about using Prism EventAggregator](/tag/eventaggregator) in .NET app development. In the previous two articles, I covered the Publisher-Subscriber pattern and benefits of using EventAggregator, and how to use it on your projects. Now that we’ve learned how to use EventAggregator in our app code, let’s write some unit tests. Unit testing is a vital part of releasing quality software, so we must test how we’ve used EventAggregator. However, it does present a few challenges. The two most important scenarios to test are:

* **Publisher**: Verify whether an event was successfully published with the correct parameter (if applicable).
* **Subscriber**: Verify whether a received event was correctly handled.

We could use the actual implementation of Prism EventAggregator. EventAggregator has very few dependencies itself, so this would probably work. But there’s a reason we shouldn’t. For a unit test, we want to isolate the code we’re testing from any kind of dependency. If we use the actual EventAggregator, our test will start to look more like an integration test rather than a unit test. So we want to use a mocked IEventAggregator instead. We’ll be using the [Moq library](https://github.com/moq/moq) for this.

## How to test with Moq

Let’s first set up our EventAggregator example. We start with an event, a publisher, and a subscriber.

Our event has a simple string as a parameter:

1

2

3

```
public class MyTextEvent : PubSubEvent<string>
{
}
```

We publish the event when the user clicks a button:

 1

 2

 3

 4

 5

 6

 7

 8

 9

10

11

12

13

14

15

16

17

18

19

20

```
public class MyPublisherViewModel
{
  private readonly IEventAggregator _eventAggregator;

  public MyPublisherViewModel(IEventAggregator eventAggregator)
  {
    _eventAggregator = eventAggregator;

    OnButtonClickCommand = new DelegateCommand(PublishTextEvent);
  }

  // ...

  private void PublishTextEvent()
  {
    _eventAggregator
      .GetEvent<MyTextEvent>()
      .Publish("text to send");
  }
}
```

The subscriber assigns the received text to a public property:

 1

 2

 3

 4

 5

 6

 7

 8

 9

10

11

12

13

14

15

16

17

18

19

20

```
public class MySubscriberViewModel
{
  private readonly IEventAggregator _eventAggregator;

  public MySubscriberViewModel(IEventAggregator eventAggregator)
  {
    _eventAggregator = eventAggregator;

    _eventAggregator
      .GetEvent<MyTextEvent>()
      .Subscribe(HandleMyTextEvent);
  }

  public string Text { get; set; }

  private void HandleMyTextEvent(string text)
  {
    Text = text;
  }
}
```

## Testing the publisher

Let’s start with the easiest problem: verifying that the event is published with the correct text when the user clicks the button. In other words, our test will have the following structure:

* **Arrange**: Set up the required mocks and instantiate the PublisherViewModel.
* **Act**: Execute the OnButtonClickedCommand.
* **Assert**: Verify that `Publish(“text to send”)` was called once.

First, we need to inject a mock of IEventAggregator into our ViewModel’s constructor:

1

2

```
var eventAggregatorMock = new Mock<IEventAggregator>();
var viewModel = new MyPublisherViewModel(eventAggregatorMock.object);
```

The only method to set up is `GetEvent<MyTextEvent>()`. This should return an instance of MyTextEvent. We need to verify something on it, so the event also has to be a mock:

1

2

3

4

```
var mockedEvent = new Mock<MyTextEvent>();
eventAggregatorMock
  .Setup(x => x.GetEvent<MyTextEvent>())
  .Returns(mockedEvent.Object);
```

Finally, let’s verify if `Publish()` is called with the correct argument. Our completed test now looks like this:

 1

 2

 3

 4

 5

 6

 7

 8

 9

10

11

12

13

14

```
// Arrange
var mockedEvent = new Mock<MyTextEvent>();
var eventAggregatorMock = new Mock<IEventAggregator>();
eventAggregatorMock
  .Setup(x => x.GetEvent<MyTextEvent>())
  .Returns(mockedEvent.Object);

var viewModel = new MyPublisherViewModel(eventAggregatorMock.object);

// Act
viewModel.OnButtonClickCommand.Execute()

// Assert
mockedEvent.Verify(x => x.Publish("text to send"), Times.Once);
```

The first unit test is done. Now on to the next one.

## Testing the subscriber

Testing the subscriber part is a bit trickier. Let’s start with a similar structure:

* Arrange: Set up the required mocks and instantiate the `SubscriberViewModel`
* Act: Execute the code that handles the event
* Assert: Verify that the `Text` property has the expected value

The problem here is in the **Act** phase. The event handling code is `HandleMyTextEvent(string text)`. This method is private, so we cannot call it directly. We don’t want to make the method public because [we shouldn’t change access modifiers to accommodate testing](https://stackoverflow.com/questions/10870449/unit-testing-and-access-modifiers-in-oo). We have to find a different approach. Somehow, we need a reference to that private method so we can invoke it manually. Luckily Moq testing provides us with a very useful method that allows us to do just that: `Callback()`.

We start off the same way as the previous test by creating mocks of `Callback()`IEventAggregator and `Callback()`MyTextEvent and setting up the `GetEvent<MyTextEvent>()` method. Next, we set up `MyTextEvent.Subscribe(Action eventHandler)`. Instead of calling `Returns<T>(T value)`, we call `Callback<T>(Action<T> callbackAction)`.

This `Callback` method receives an `Action` that is called whenever the method being set up is called. If the method being set up receives any arguments, those will be passed into the `Action` as well. In our case, `Subscribe()` will receive an `Action<Action>` argument, so our callback action will be `Action`. In other words, our `callbackAction` will receive a reference to the Action that’s passed into `Publish()` in the constructor of `SubscriberViewModel`. All we need to do is save that reference so we can invoke it later. This all sounds a bit complicated, so here it is in code:

1

2

3

4

5

6

```
Action<string> eventHandlerAction;
var mockedEvent = new Mock<MyTextEvent>();

mockedEvent
  .Setup(x => x.Subscribe(It.IsAny<Action<string>>()))
  .Callback(action => eventHandlerAction = action); // We store the action passed here in a variable, so we can access it later in our test.
```

Unfortunately, this code will throw an exception. Moq can’t setup `Subscribe(Action<string>action)` because that’s actually an extension method. Instead, we need to set up the method with all of its optional parameters:

1

2

3

4

5

6

7

```
mockedEvent
  .Setup(x => x.Subscribe(
    It.IsAny<Action<string>>(),      // The event handler
    It.IsAny<ThreadOption>(),        // threadOption
    It.IsAny<bool>(),                // keepSubscriberReferenceAlive
    It.IsAny<Predicate<string>>()))  // filter
.Callback((action, _, __, ___) => eventHandlerAction = action); // We're only interested in the action argument, so we discard the others
```

Now that we have a reference to the event handler action, we can complete our Act phase. So our complete test will look like this:

 1

 2

 3

 4

 5

 6

 7

 8

 9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

```
// Arrange
Action<string> eventHandlerAction;

var mockedEvent = new Mock<MyTextEvent>();
mockedEvent
  .Setup(x => x.Subscribe(
    It.IsAny<Action<string>>(),     // The event handler
    It.IsAny<ThreadOption>(),       // threadOption
    It.IsAny<bool>(),               // keepSubscriberReferenceAlive
    It.IsAny<Predicate<string>>())) // filter
.  Callback((action, _, __, ___) => eventHandlerAction = action);

var eventAggregatorMock = new Mock<IEventAggregator>();
eventAggregatorMock
.Setup(x => x.GetEvent<MyTextEvent>())
.Returns(mockedEvent.Object);

var viewModel = new MyPublisherViewModel(eventAggregatorMock.object);

// Act
eventHandlerAction.Invoke("expected");

// Assert
myTextEvent.Equal("expected", viewModel.Text);
```

Wow, we finally have a working unit test. But that’s a LOT of code. There should be a more elegant way to do this, right? Enter [EventAggregator\_Mocker](https://github.com/kristofberge/EventAggregator%5FMocker).

## Nuget package EventAggregator\_Mocker

With the magic of refactoring and the miracle of extension methods I made this neat little [nuget package](https://www.nuget.org/packages/EventAggregator%5FMocker/). To use it, just add the package to your test project and you’re good to go.

The package contains two extension methods for `Mock<IEventAggregator>`:

* `Mock<TEvent> RegisterNewMockedEvent<TEvent>(Action<Action>onSubscribeAction = null)` for mocking events without a parameter
* `Mock<TEvent> RegisterNewMockedEvent<TEvent, TParam>(Action<Action<TParam>> onSubscribeAction = null)` for mocking events _with_ a parameter

Both of these will return a mocked event that’s already registered within the mocked `IEventAggragator`. Also, they each have an optional Action parameter used as callback action, so we can get the reference to our event handling action.

With this package, our unit tests from above will now look like this:

**Publisher:**

 1

 2

 3

 4

 5

 6

 7

 8

 9

10

```
// Arrange
var eventAggregatorMock = new Mock<IEventAggregator>();
Mock<MyTextEvent> mockedEvent = eventAggregatorMock.RegisterNewMockedEvent(); // We don't need a reference to the event handler, so we don't pass an Action.
var viewModel = new MyPublisherViewModel(eventAggregatorMock.object);

// Act
viewModel.OnButtonClickCommand.Execute();

// Assert
mockedEvent.Verify(x => x.Publish("text to send"), Times.Once);
```

**Subscriber**:

 1

 2

 3

 4

 5

 6

 7

 8

 9

10

11

```
// Arrange
Action<string> eventHandlerAction;
var eventAggregatorMock = new Mock<IEventAggregator>();
_ = eventAggregatorMock.RegisterNewMockedEvent<MyTextEvent>(action => eventHandlerAction = action); // We don't need the event, so we discard the return value.
var viewModel = new MyPublisherViewModel(eventAggregatorMock.object);

// Act
eventHandlerAction.Invoke("expected");

// Assert
myTextEvent.Equal("expected", viewModel.Text);
```

Well, those code blocks are much shorter and more readable. You can find the source code of the package [here](https://github.com/kristofberge/EventAggregator%5FMocker). If you want to see it in action, there’s a [working example](https://github.com/kristofberge/EventAggregator%5FMocker/tree/master/Examples/Xamarin.Forms/EventAggregatorTest.UnitTests/ViewModels). I hope you found this [series on Prism EventAggregator](/tag/eventaggregator) useful. Make sure to follow us on [Facebook](https://www.facebook.com/arctouch/), [Twitter](https://twitter.com/ArcTouch), and [LinkedIn](https://www.linkedin.com/company/279553/admin/) and let us know what you think of it.

## Need help with your .NET app development project?

ArcTouch has been designing and developing apps for leading companies since the dawn of the app store. [Contact us](/contact) if you need advice or help with your latest app projects. From [cross-platform Xamarin app development](/xamarin-developers) to native Android and iOS projects, we’re here to help.

## Article Author:

[KB | Kristof Bergé | ArcTouch employee](/blog/author/kristof-berge)

## Tags:

[Agile Development](/tag/agile-development) [Developer Tips](/tag/developer-tips) [Enterprise Applications](/tag/enterprise-applications) [EventAggregator](/tag/eventaggregator) [Microsoft](/tag/microsoft) [Xamarin](/tag/xamarin)

## Subscribe for more insights

Get our newsletter in your inbox.

## Related posts

[12 web accessibility best practices: A starter list | ArcTouch shares 12 best practices that provide a great starting point for building accessible web experiences. | 5 min. read - April 16, 2024](/blog/web-accessibility-best-practices) [Injecting AI into software development — an ArcTouch blog series | The ArcTouch design and development team shares how to use AI to build lovable apps and websites — better and faster. | 5 min. read - April 9, 2024](/blog/ai-software-development)

## Contact us.

### Let's build something lovable. Together.

We help companies of all sizes build lovable apps, websites, and connected experiences.
