我想存根一个方法,它使用一个块作为参数使用Kiwi.以下是代码的完整说明:
我有一个名为TestedClass的类,它有一个方法testsMethod,它依赖于类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将blockMethod与块一起存储以便对单元测试testMethod进行单元测试?
更新:在Kiwi中找到了如何做到这一点,请参阅下面的答案.
解决方法
以下是您在Kiwi中的表现:
首先,你必须依赖注入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:时捕获第一个参数中的块.现在,是时候实际执行块了.
这里很容易混淆,所以我会强调这一点:通话顺序很重要;你首先声明间谍,然后调用测试的方法,然后你才真正调用并执行块!
这将使您能够检查您想要的是什么,因为您是执行块的人.
希望它对其他人有所帮助,因为我花了很长时间来理解这个流程.