私が使用したオプションの1つはstub:withBlock:
NSArray* capturedArray; // declare this as __block if needed
[aMockObject stub:@selector(doSomething:)
withBlock:^id(NSArray *params) {
capturedArray = params[0];
// this is necessary even if the doSomething method returns void
return nil;
}];
// exercise your object under test, then:
[[capturedArray should] haveCountOf:3U];
これは問題なく機能し、スパイパターンよりも実装が簡単だと思います。しかし、あなたの質問は、メッセージパターンを使用した期待について疑問に思いました。例えば:
[[[aMockObject should] receive] doSomething:myArray];
[[[aMockObject should] receive] doSomething:any()];
最初の例では、引数が。のメッセージをaMockObject
受信したことを確認します。2番目の例では、アレイの拡張については予期せずに、送信されたことを確認するだけです。メッセージパターンで特定のタイプのMatcherを指定して、メッセージで送信される特定の配列インスタンスを気にせず、3の場合だけであることを表現できれば素晴らしいと思います。doSomething:
isEqual:myArray
doSomething:
count
これができる例は見つかりませんでしたが、いくつかの可能性があるようです。メッセージ送信の期待を検証するために、KiwiはKWMessagePattern
クラス、特にmatchesInvocation:
andargumentFiltersMatchInvocationArguments:
メソッドを使用します。これにより、次の3種類の「引数フィルター」がチェックされます。
- リテラルオブジェクトの値(
myArray
上記の例など)。これは、を使用してメッセージで送信された実際の値と比較されます。isEqual:
- 任意の引数値と一致するタイプのオブジェクト
KWAny
(上記の例のマクロなど)any()
- を満たすオブジェクト
[KWGenericMatchEvaluator isGenericMatcher:argumentFilter]
。これは基本的に、オブジェクトがに応答することを意味します。matches:(id)obj
したがって、メッセージパターンの期待値を実装するオブジェクトを使用してmatches:
、スパイやブロックに頼ることなく、スタブメソッドに送信される配列の長さを検証するなどのことができるはずです。これは非常に単純な実装です:(要点として利用可能)
// A reusable class that satisfies isGenericMatcher:
@interface SOHaveCountOfGenericMatcher : NSObject
- (id)initWithCount:(NSUInteger)count;
- (BOOL)matches:(id)item; // this is what KWMessagePattern looks for
@property (readonly, nonatomic) NSUInteger count;
@end
@implementation SOHaveCountOfGenericMatcher
- (id)initWithCount:(NSUInteger)count
{
if (self = [super init]) {
_count = count;
}
return self;
}
- (BOOL)matches:(id)item
{
if (![item respondsToSelector:@selector(count)])
return NO;
return [item count] == self.count;
}
@end
// Your spec:
it(@"should receive an array with count 3", ^{
NSArray* testArray = @[@"a", @"b", @"c"];
id argWithCount3 = [[SOHaveCountOfGenericMatcher alloc] initWithCount:3];
id aMockObject = [SomeObj nullMock];
[[[aMockObject should] receive] doSomething:argWithCount3];
[aMockObject doSomething:testArray];
});
ここでKiwiの組み込みマッチャークラスを再利用できると便利ですが、これを行う方法はまだ正確にはわかりません。