views:

380

answers:

3

I use Composite WPF(Prism) and I am trying to unit test that my Controller does in fact subscribe to a Composite Event.

My subscription code looks as follows...

//Init Events.
this.eventAggregator.GetEvent<PlantTreeNodeSelectedEvent>().Subscribe(
    ShowNodeDetails, ThreadOption.UIThread);

My unit testing code looks as follows (I use Moq as my Mocking Framework and Unity as my DI Framework)...

Mock<PlantTreeNodeSelectedEvent> eventBeingListenedTo = new Mock<PlantTreeNodeSelectedEvent>();
eventAggregatorMock.Setup(e => e.GetEvent<PlantTreeNodeSelectedEvent>()).Returns(eventBeingListenedTo.Object);


//Initialize the controller to be tested.
IPlantTreeController controllerToTest = container.Resolve<IPlantTreeController>();


//Verify.
eventBeingListenedTo.Verify(
    e => e.Subscribe(It.IsAny<Action<string>>(), ThreadOption.UIThread));

This subscribe method IS being called (I've verified by running with the debugger), but the Verify always fails with "Invocation was not performed on the mock: e => e.Subscribe..."

Any idea what I am doing wrong?

A: 

In your code, it seems like the eventAggregatorMock instance is never used. I would guess that you need to register it with the container so that it is being used by controllerToTest.

Mark Seemann
A: 

I am having the same problem. I believe it is because the test does not create a UI thread for the callback. Try the test without ThreadOption.UIThread. Unfortunately I have yet to find a good way to test events that are expected to callback on the UI thread.

Edit: Scratch this, I thought you were testing the actual callback not the fact that subscribe was called.

Chris Nicola
A: 
  1. You seem to be testing too much in your unit test. You shouldn't need a container, you should just create your controller providing mock dependencies, because you should only test 1 thing in a unit test (you don't need to test that the DI framework works, as it usually does ;-)). It will also ensure that you provide the correct mocks, now it is not clear from your code as Mark Seemann has pointed out in his answer.

  2. You may try to setup a method call under question in the beginning. Sometimes it seems to help moq to verify the class appropriately. In this case you may also want to setup your mock behavior to be Strict in the constructor, so that you will get the test failed for other, unexpected calls to your mock.


eventBeingListenedTo.Setup(e => e.Subscribe(It.IsAny<Action<string>>(), ThreadOption.UIThread));
Yacoder