2014-01-09 64 views
0

我正在使用Prism框架和Moq一起使用。我試圖驗證AlarmService是否在構造函數中訂閱了一個事件,但我收到了一個不支持的異常。使用Moq驗證棱鏡事件訂閱失敗

我還能如何驗證?

這是我的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得到上面的代碼,但它仍然失敗。

回答

1

您只能模擬/驗證虛擬或接口方法。看起來像Subscribe不是一種虛擬方法。 Moq(和其他一些框架)使用Castle Project的DynamicProxy在運行時動態生成代理,以便在不修改類的代碼的情況下攔截對象的成員。截取只能在公共虛擬和受保護的虛擬方法上完成。

請參見下面的網址瞭解更多信息:http://www.castleproject.org/projects/dynamicproxy/

更新:對於您不能修改,您可以使用與Microsoft僞造品框架墊片的代碼。注意:使用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)?

+0

這確實不是虛擬的,令我困惑的是取消訂閱方法是虛擬的,但訂閱方法不是。 – uncletall

+0

我更新了提及Msft Fakes框架的答案。 –

+0

謝謝,我添加了一個工作解決方案。然而,我並不喜歡它,因爲我正在測試Subscribe方法的內部實現方式。 – uncletall

1

我想這個問題是,訂閱方法重載,最終調用另一個訂閱方法有哪些是虛擬的更默認選項。通過更改測試來驗證此虛擬方法,我可以驗證訂閱方法已被調用。

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