7

我想存根一个使用 Kiwi 将块作为参数的方法。这是带有代码的完整解释:

我有一个名为的类TestedClass,它有一个testedMethod依赖于NetworkClass通过 AFNetworking 调用到服务器的类的方法,并通过块返回其响应。翻译成代码:

@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];
}

我如何使用 Kiwi 存根networkMethod与块以进行单元测试testMethod

更新:找到如何在 Kiwi 中执行此操作,请参阅下面的答案。

4

1 回答 1

11

这是在 Kiwi 中执行此操作的方法:

首先,你必须依赖注入NetworkClassTestedClass(如果不清楚如何,请添加评论,我会解释;为了简单起见,这可以作为一个属性来完成。这样你就可以对模拟对象进行操作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 回答