簡體   English   中英

OCMock:模擬協議未正確停止

[英]OCMock: mocked protocol isn't stopped correctly

我有一個使用OCMock的測試用例,它執行以下操作:

CAAOAuth2AuthenticationManager *oAuth2AuthManager = [[CAAOAuth2AuthenticationManager alloc] init];
id authDelegate = [OCMockObject mockForProtocol:@protocol(CAAAuthenticationDelegate)];
id partialAuthManagerMock = [OCMockObject partialMockForObject:oAuth2AuthManager];
id resultMock = [OCMockObject mockForClass:[CAAOAuth2AuthenticationResult class]];
[[authDelegate reject] didFailWithError:OCMOCK_ANY];

[[[partialAuthManagerMock expect] andForwardToRealObject] authenticateWithResult:OCMOCK_ANY formData:OCMOCK_ANY delegate:authDelegate];
[[partialAuthManagerMock reject] authenticateWithOptions:OCMOCK_ANY delegate:authDelegate];

[[[resultMock expect] andReturnValue:OCMOCK_VALUE(YES) ] isAuthenticated];
[[resultMock reject] refreshToken];

當我運行測試用例時,另一個也使用CAAAuthenticationDelegate協議的測試用例(完全不同的測試類和文件)在SIGABRT中失敗:

2014-02-28 10:11:24.594 otest[37161:303] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'OCMockObject[CAAAuthenticationDelegate]: unexpected method invoked: didReceiveAuthenticationWithResult:OCMockObject[CAAOAuth2AuthenticationResult] 
stubbed:    didFailWithError:<OCMAnyConstraint: 0xa913fc0>'

但是,我在第二個測試用例中不使用任何模擬。 我試圖用stopMocking清除stopMocking ,但沒有成功。

以下模擬設置可以正常工作:

[[authDelegate reject] didFailWithError:OCMOCK_ANY];

[[[partialAuthManagerMock expect] andForwardToRealObject] authenticateWithResult:OCMOCK_ANY formData:OCMOCK_ANY delegate:authDelegate];
[[partialAuthManagerMock expect] authenticateWithOptions:OCMOCK_ANY delegate:authDelegate];

[[[resultMock expect] andReturnValue:OCMOCK_VALUE(NO) ] isAuthenticated];
[[[resultMock expect] andReturn:refreshToken] refreshToken];

誰能告訴我,為什么會這樣?

作為一種解決方法,您可以創建協議的空實現,然后模擬真實對象嗎? 我對這種方法有更好的把握-模擬協議對我來說只是個傻瓜。

@interface TestAuthDelegateImpl : NSObject <CAAAuthenticationDelegate>
@end
@implementation
- (void)didFailWithError:(id)whatever;
@end

這樣的事情。 然后只是嘲笑它-可能會表現得更好。

這似乎意味着您的CAAOAuth2AuthenticationManager實例在以后的測試中仍然存在,並且仍在其上設置了舊的模擬委托,並且在其上調用了某些方法,從而導致調用了該委托方法。 CAAOAuth2AuthenticationManager是單個類型的對象,還是在第二個測試中使用的實例相同? 完成后,我會在第一個測試中將委托管理器上的委托重置為nil。

您還可以使用niceMockForProtocol,它將靜默忽略任何未在其上設置顯式拒絕的方法調用。 異常情況下,聽起來好像拒絕已被刪除,並且委托模擬現在將只對發送給它的任何方法拋出異常,因為也沒有期望值。

另外,我將在對您的真實代碼的實際調用周圍使用STAssertNoThrow()(大概在您上面顯示的設置之后發生)。 拒絕和意外方法將引發異常,這可能導致模擬對象無法正確釋放,並為后續測試造成問題。 如果有問題的測試通過了,那可能就不是問題了。

最后要檢查的是您的委托屬性是否聲明為“ assign”而不是“ weak”。 如果它是“賦值”,而您沒有將其清除,而是將其釋放,則可能會發生任何事情(段錯誤,或在同一內存地址分配了一個全新的對象)。 不過,這似乎不太可能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM