0

I am using the Prism framework together with Moq. I am trying to verify that the AlarmService subscribes to an event in the constructor but I am getting an exception that this is not supported.

How else can I verify this?

This is my testMethod:

public void TestMethod()
{
    var mockMachineDataService = new Mock<IMachineDataService<AlarmDto>>();
    var mockAggregator = new Mock<IEventAggregator>();
    var mockEvent = new Mock<MachineMessageReceivedEvent>();
    mockAggregator.Setup(x => x.GetEvent<MachineMessageReceivedEvent>()).Returns(mockEvent.Object);

    var alarmService = new AlarmService(mockAggregator.Object, mockMachineDataService.Object);
    Assert.IsNotNull(alarmService);

    mockAggregator.VerifyAll();
    mockEvent.Verify(x => x.Subscribe(It.IsAny<Action<MachineMessage>>(), It.IsAny<ThreadOption>()));
}

When I am running this I get the following failure:

System.NotSupportedException: Invalid verify on a non-virtual (overridable in VB) member: x => x.Subscribe(It.IsAny<Action`1>(), It.IsAny<ThreadOption>())

I did have a look at this and split up the mockAggregator and mockEvent to get the above code, but it still fails.

Community
  • 1
  • 1
uncletall
  • 6,609
  • 1
  • 27
  • 52

2 Answers2

2

I guess the problem was that the Subscribe method is overloaded and in the end calls another Subscribe method with more default options which is virtual. By changing the test to verify this virtual method I can verify that the subscribe method has been called.

[TestMethod]
public void TestConstructorSubscribesToMachineMessages()
{
    var mockMachineDataService = new Mock<IMachineDataService<AlarmDto>>();
    var mockAggregator = new Mock<IEventAggregator>();
    var mockEvent = new Mock<MachineMessageReceivedEvent>();
    mockAggregator.Setup(x => x.GetEvent<MachineMessageReceivedEvent>()).Returns(mockEvent.Object);
    mockEvent.Setup(x => x.Subscribe(It.IsAny<Action<MachineMessage>>(), It.IsAny<ThreadOption>(), It.IsAny<bool>(), It.IsAny<Predicate<MachineMessage>>()));

    var alarmService = new AlarmService(mockAggregator.Object, mockMachineDataService.Object);
    Assert.IsNotNull(alarmService);

    mockAggregator.VerifyAll();
    mockEvent.VerifyAll();
}
uncletall
  • 6,609
  • 1
  • 27
  • 52
1

You can only Mock/Verify a Virtual or an interface method. Looks like Subscribe is not a virtual method.

Moq (and few other frameworks) uses Castle Project's DynamicProxy to generate proxies on the fly at run-time so that members of an object can be intercepted without modifying the code of the class. That interception can only be done on public virtual and protected virtual methods.

See below URL for more information: http://www.castleproject.org/projects/dynamicproxy/

UPDATE: For the code that you can't modify you can use Shims available with Microsoft Fakes framework. Note: Its not a good practice to use Shims for your own code.

http://msdn.microsoft.com/en-us/library/hh549175.aspx

How can I verify that a Microsoft Fakes (beta) stub/shim was called (like AssertWasCalled in Rhino Mocks)?

Community
  • 1
  • 1
Adarsh Shah
  • 6,755
  • 2
  • 25
  • 39
  • It is indeed not virtual, what confuses me is that the Unsubscribe method is virtual but the Subscribe method is not. – uncletall Jan 09 '14 at 07:53
  • Thanks, I added a working solution. However, I am not so happy with it as in a way I am testing the internal implementation of the Subscribe method.. – uncletall Jan 09 '14 at 08:12
  • Microsoft Shims and Stubs are only available from VS 2012 Ultimate and Premium upwards... I am still stuck on VS 2010 Professional.. time to talk to my boss ;) – uncletall Jan 09 '14 at 08:25
  • Yes that's true. You need to upgrade for that. – Adarsh Shah Jan 09 '14 at 08:26
  • Do you know if everybody then needs to get the Ultimate or Premium license? The price diff between 2013 Pro and Premium is a factor 8.... I guess I can get my boss to give me one Premium.... but not 10.... – uncletall Jan 09 '14 at 08:31
  • The tests will fail if u don't have that license and u r using fakes. You do need to get for all unless u r the only one running those tests – Adarsh Shah Jan 09 '14 at 08:51