7

Kiwi を使用してブロックをパラメーターとして受け取るメソッドをスタブしたいと考えています。コード付きの完全な説明は次のとおりです。

AFNetworkingを介してサーバーを呼び出し、ブロックを介してその応答を返すクラスに依存TestedClassするメソッドを持つという名前のクラスがあります。コードへの変換:testedMethodNetworkClass

@interface TestedClass : NSObject
    -(void)testMethod;
@end

-(void)testMethod
{
    NetworkClass *networkClass = [[NetworkClass alloc] init];

    [networkClass networkMethod:^(id result)
    {
        // code that I want to test according to the block given which I want to stub
        ...
    }];
}



typedef void (^NetworkClassCallback)(id result);

 @interface NetworkClass : NSObject
 -(void)networkMethod:(NetworkClassCallback)handler;
 @end

-(void) networkMethod:(NetworkClassCallback)handler
{
    NSDictionary *params = @{@"param":@", @"value"};
    NSString *requestURL = [NSString stringWithFormat:@"www.someserver.com"];
    AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURLURLWithString:requestURL]];
    NSURLRequest *request = [httpClient requestWithMethod:@"GET" path:requestURL parameters:params];
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
         handler(responseObject);
    }

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    handler(nil);
}];

[operation start];
}

networkMethod単体テストを行うためにKiwi を使用してブロックでスタブするにはどうすればよいtestMethodですか?

更新:キウイでこれを行う方法を見つけました。以下の私の回答を参照してください。

4

1 に答える 1

11

キウイでこれを行う方法は次のとおりです。

NetworkClassまず、依存関係を注入する必要がありますTestedClass(方法が明確でない場合は、コメントを追加してください。説明します。簡単にするために、これをプロパティとして行うことができます。これは、のモック オブジェクトを操作できるようにするためですNetworkClass) 。

次に、仕様、ネットワーク クラスのモックを作成し、単体テストするクラスを作成します。

SPEC_BEGIN(TestSpec)

describe(@"describe goes here", ^{
    it(@"should test block", ^{
        NetworkClass *mockNetworkClass = [NetworkClass mock];
        KWCaptureSpy *spy = [mockNetworkClass captureArgument:@selector(networkMethod:) atIndex:0];
        TestedClass testClass = [TestedClass alloc] init];
        testClass.networkClass = mockNetworkClass;
        [testClass testMethod];

        NetworkClassCallback blockToRun = spy.argument;
        blockToRun(nil);

        // add expectations here

    });
});

SPEC_END

ここで何が起こっているかを説明するには:

を作成TestedClassして呼び出してtestMethodいます。ただし、その前に、 と呼ばれるものを作成しています。Spyその仕事は、 が呼び出されたときに最初のパラメーターでブロックをキャプチャすることnetworkMethod:です。ここで、実際にブロック自体を実行します。

ここで混乱しやすいので、ここで強調しておきます。呼び出しの順序は重要です。最初にスパイを宣言し、次にテストされたメソッドを呼び出します。その後で初めて、実際にブロックを呼び出して実行します!

これにより、ブロックを実行しているので、必要なものを確認できます。

この流れを理解するのにかなり時間がかかったので、それが他の人に役立つことを願っています.

于 2013-11-27T11:49:00.410 に答える