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?
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
.
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.
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));
use a mocking aggregator like this (for Rhino.Mocks)
http://adammills.wordpress.com/2010/12/13/auto-mocking-eventaggregator/
If you use ThreadOption.UIThread, it calls Dispatcher.Invoke which won't work without a Message Loop; which isn't normally running in unit tests.