jlu*_*jan 5 xcode ios xctest afnetworking-2
我正在尝试使用XCTest对在XCode 5中使用AFNEtworking的类进行单元测试.我遇到的问题是我的AFHTTPRequestOperation的完成块永远不会被执行.我假设这是运行单元测试的XCode和AFNetworking的调度队列之间的一些脱节.以下测试用例通过,但永远不会到达完成块中的NSLog语句(没有日志输出,也没有捕获这些语句上设置的断点).相同的代码在单元测试之外工作.有谁知道如何解决这个问题?我正在使用Nocilla来模拟实际的请求,结果是使用真正的服务器重新调整有效响应?
编辑以使测试失败并在块中设置日志变量
- (void)setUp
{
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
[[LSNocilla sharedInstance] start];
stubRequest(@"POST", @"http://www.example.com/module/api/ping").
andReturn(200).
withHeaders(@{@"Content-Type": @"application/json"}).
withBody(@"{\"success\":true}");
stubRequest(@"GET", @"http://www.example.com/module/api/ping?testkey=testval").
andReturn(200).
withHeaders(@{@"Content-Type": @"application/json"}).
withBody(@"{\"success\":true}");
}
- (void)tearDown
{
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
[[LSNocilla sharedInstance] stop];
[[LSNocilla sharedInstance] clearStubs];
}
- (void)testSanity
{
AFSecurityPolicy *policy = [[AFSecurityPolicy alloc] init];
//[policy setAllowInvalidCertificates:YES];
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:@"http://www.example.com/module/api/ping"]];
//manager.operationQueue = [NSOperationQueue mainQueue];
[manager setSecurityPolicy:policy];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
__block id resObj = nil;
__block id resError = nil;
AFHTTPRequestOperation *req = [manager POST:@"http://www.example.com/module/api/ping"
parameters:[NSDictionary dictionaryWithObject:@"testval" forKey:@"testkey"]
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"Response: %@", responseObject);
resObj = responseObject;
return;
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
resError = error;
return;
}];
[req waitUntilFinished];
NSLog(@"req.status: %d", req.response.statusCode);
NSLog(@"req.responseObj: %@", req.responseObject);
XCTAssertTrue(req.isFinished);
NSLog(@"resObj: %@", resObj);
NSLog(@"resError: %@", resError);
XCTAssertEqual([[req.responseObject objectForKey:@"success"] boolValue], YES);
XCTAssertEqual([[resObj objectForKey:@"success"] boolValue], YES);
}
Run Code Online (Sandbox Code Playgroud)
控制台输出
Test Case '-[AppSupportTests testSanity]' started.
2014-04-29 16:45:07.424 xctest[72183:303] req.status: 200
2014-04-29 16:45:07.424 xctest[72183:303] req.responseObj: {
success = 1;
}
2014-04-29 16:45:07.424 xctest[72183:303] resObj: (null)
2014-04-29 16:45:07.425 xctest[72183:303] resError: (null)
/Users/jlujan/Code/AppSupport/AppSupportTests/AppSupportTests.m:114: error: -[AppSupportTests testSanity] : (([[resObj objectForKey:@"success"] boolValue]) equal to (__objc_yes)) failed: ("NO") is not equal to ("YES")
Test Case '-[AppSupportTests testSanity]' failed (0.003 seconds).
根据评论中的讨论,我们发现waitUntilFinished一旦后台操作完成,它就不会等到调用完成块之后。
有一个更好的异步测试框架 - Expecta。
然后而不是调用:
XCTAssertTrue(req.isFinished);
XCTAssertEqual([[resObj objectForKey:@"success"] boolValue], YES);
Run Code Online (Sandbox Code Playgroud)
你可以做:
expect(req.isFinished).will.beTruthy();
expect([[resObj objectForKey:@"success"] boolValue]).will.beTruthy();
Run Code Online (Sandbox Code Playgroud)
还有很多其他匹配器,只需确保您在方法中设置了超时即可。+[Expecta setAsynchronousTestTimeout:]+setUp
| 归档时间: |
|
| 查看次数: |
1872 次 |
| 最近记录: |