Using Moq to verify a Prism event subscription fails

馋奶兔 提交于 2019-12-13 05:13:17

问题


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.


回答1:


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();
}



回答2:


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)?



来源:https://stackoverflow.com/questions/21014195/using-moq-to-verify-a-prism-event-subscription-fails

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!