我正在使用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来获取上面的代码,但它仍然失败。
答案 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用于自己的代码并不是一个好习惯。