问题
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