2

OCMockitoとOCHamcrestを使用して、モックされたメソッドへの引数に期待値を設定できます。

[verify(aMockObject) doSomething:allOf(is(instanceOf([NSArray class])), hasCountOf(3U), nil)];

Kiwiを使用してこれを行うための同等の簡単な方法はないようです。次のようなスパイを使用して引数をキャプチャすることができます。

KWCaptureSpy *spy = [aMockObject captureArgument:@selector(doSomething:) atIndex:0];
NSArray *capturedArray = spy.argument;

次に、キャプチャされたオブジェクトに対する期待を確認します。

[[capturedArray should] haveCountOf:3U];

キウイでこれを行うためのより不器用な方法はありますか?

(私はおそらくここでハムクレストマッチャーを使用できることを知っていますが、今のところ私はキウイが何ができるかを探っています)。

4

1 に答える 1

4

私が使用したオプションの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:myArraydoSomething:count

これができる例は見つかりませんでしたが、いくつかの可能性があるようです。メッセージ送信の期待を検証するために、KiwiはKWMessagePatternクラス、特にmatchesInvocation:andargumentFiltersMatchInvocationArguments:メソッドを使用します。これにより、次の3種類の「引数フィルター」がチェックされます。

  1. リテラルオブジェクトの値(myArray上記の例など)。これは、を使用してメッセージで送信された実際の値と比較されます。isEqual:
  2. 任意の引数値と一致するタイプのオブジェクトKWAny(上記の例のマクロなど)any()
  3. を満たすオブジェクト[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の組み込みマッチャークラスを再利用できると便利ですが、これを行う方法はまだ正確にはわかりません。

于 2013-03-28T03:04:22.113 に答える