使用Moq验证Prism事件订阅失败

时间:2014-01-09 07:34:54

标签: c# moq prism

我正在使用Prism框架和Moq。我试图验证AlarmService订阅构造函数中的事件,但我得到一个异常,这是不支持的。

我还能如何验证这一点?

这是我的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>()));
}

当我运行时,我遇到以下故障:

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

我确实查看了this并拆分了mockAggregator和mockEvent来获取上面的代码,但它仍然失败。

2 个答案:

答案 0 :(得分:2)

我想问题是Subscribe方法是重载的,最后调用另一个具有更多默认选项的Subscribe方法是虚拟的。通过更改测试以验证此虚方法,我可以验证是否已调用subscribe方法。

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

答案 1 :(得分:1)

您只能模拟/验证虚拟或界面方法。看起来Subscribe不是虚拟方法。

Moq(以及其他一些框架)使用Castle Project的DynamicProxy在运行时动态生成代理,以便可以截获对象的成员而无需修改类的代码。该拦截只能在公共虚拟和受保护的虚拟方法上完成。

有关详细信息,请参阅以下网址:http://www.castleproject.org/projects/dynamicproxy/

更新:对于无法修改的代码,可以使用Microsoft Fakes框架提供的Shims。注意:将Shims用于自己的代码并不是一个好习惯。

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