私の日常の仕事では、 Mockitoのnever()
verify で甘やかされてしまいました。これにより、モックメソッドが呼び出されないことが確認できます。
Objective-CとOCMockを使用して同じことを達成する方法はありますか?私は以下のコードを使用していますが、これは機能しますが、ハックのように感じます。もっと良い方法があるといいのですが...
- (void)testSomeMethodIsNeverCalled {
id mock = [OCMockObject mockForClass:[MyObject class]];
[[[mock stub] andCall:@selector(fail) onObject:self] forbiddenMethod];
// more test things here, which hopefully
// never call [mock forbiddenMethod]...
}
- (void)fail {
STFail(@"This method is forbidden!");
}
OCMockのr69以降、メソッド呼び出しを拒否することが可能です http://svn.mulle-kybernetik.com/OCMock/trunk/Source/Changes.txt
素晴らしいモック/高速で失敗するexpectまたはstubのいずれかで設定されていないモックオブジェクトでメソッドが呼び出されると、モックオブジェクトで例外が発生します。このフェイルファストモードは、「素敵な」モックを作成することでオフにできます。
id mock = [OCMockObject niceMockForClass:[SomeClass class]]
ニースモックは予期しないメソッドをすべて無視するだけですが、特定のメソッドを禁止することは可能です。
[[mock reject] someMethod]
フェイルファストモードでは、例外が無視されると、verifyが呼び出されたときに例外が再スローされることに注意してください。これにより、通知などからの不要な呼び出しを確実に検出できます。
引用元: http://www.mulle-kybernetik.com/software/OCMock/#features
私の知る限り、verifyを呼び出し、記録されていないメソッドが呼び出されると、OCMockは自動的に失敗します。予期しないメソッドが呼び出されても文句を言わないモックは、「ナイスモック」と呼ばれます。
- (void)testSomeMethodIsNeverCalled {
id mock = [OCMockObject mockForClass:[MyObject class]];
[mock forbiddenMethod];
[mock verify]; //should fail
}
バージョン3.3以降、OCMockには OCMReject マクロがあります。
id mock = OCMClassMock([MyObject class]);
OCMReject([mock forbiddenMethod]);
// exception will raise
[mock forbiddenMethod];
また、部分的にモックしているオブジェクトでメソッドが呼び出されないようにする必要がある場合もあります。
このためのマクロを作成しました:
#define andDoFail andDo:^(NSInvocation *invocation) { STFail(@"Should not have called this method!"); }
私はそれを次のように使用します:
[[[_myPartialMock stub] andDoFail] unexpectedMethod];
メソッドが呼び出されないようにするには、testMethod
が呼び出される前にアサートを実行する必要があると思います。したがって、テストメソッドを実行する前に必ずOCMReject
を入力して、testMethod
の実行時にどのメソッドがトリガーされるかをリッスンしてください。
OCMReject([mock someMethod]);
[mock testMethod];
次のようなJavaScriptを試すこともできます。
- (void)aMethod {
__block BOOL b = NO;
id mock = [OCMockObject mockForClass:[UIView class]];
[[[mock stub] andDo:^(NSInvocation *i) { b = YES; }] resignFirstResponder];
[mock resignFirstResponder];
NSLog(@"And b is: %i", b); // This reads "And b is: 1" on the console
}
このコードに関連するリークがあるかどうかはわかりません。私はこのページを読んでアイデアを得ました: http://thirdcog.eu/pwcblocks/