0

次のことを行う 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 プロトコルも使用する 2 番目のテスト ケース (完全に異なるテスト クラスとファイル) が 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>'

ただし、2 番目のテスト ケースではモックを使用しません。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];

なぜこれが起こるのか、誰か教えてもらえますか?

4

2 に答える 2

0

回避策として、プロトコルの空の実装を作成してから、実際のオブジェクトをモックできますか? 私はその方法で運が良かった - プロトコルをあざけることは、私にとっておかしさにつながるだけだった。

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

そんな感じ。次に、mockForClass を実行するだけで、動作が改善される可能性があります。

于 2014-02-28T19:00:11.747 に答える
0

これは、CAAOAuth2AuthenticationManager インスタンスがまだ後のテストで使用されていて、古いモック デリゲートが設定されていて、そのデリゲート メソッドが呼び出される原因となったメソッドが呼び出されたことを意味しているようです。CAAOAuth2AuthenticationManager はシングルトン タイプのオブジェクトですか、それとも 2 番目のテストで同じインスタンスが使用されていますか? 最初のテストが完了したら、認証マネージャーでデリゲートを nil にリセットします。

また、niceMockForProtocol を使用することもできます。これは、明示的な拒否が設定されていないメソッド呼び出しを黙って無視します。例外によって、拒否が削除されたように聞こえます。デリゲート モックは、送信されたすべてのメソッドに対して例外をスローするようになりました。

また、実際のコードへの実際の呼び出しの周りで STAssertNoThrow() を使用します (これは、おそらく上記のセットアップの後に発生します)。拒否や予期しないメソッドによって例外が発生し、モック オブジェクトの割り当てが適切に解除されず、後続のテストで問題が発生する可能性があります。ただし、問題のテストに合格した場合、それはおそらくここでは問題ではありません。

最後に確認することは、デリゲート プロパティが "weak" ではなく "assign" として宣言されているかどうかです。それが「割り当て」であり、それを nil アウトせずに解放された場合、何かが発生する可能性があります (セグメンテーション違反、またはまったく新しいオブジェクトが同じメモリ アドレスに割り当てられます)。ここでもそれはありそうにありません。

于 2014-03-09T15:58:38.767 に答える