我想知道如何使用 NSURLSession 对 HTTP 请求和响应进行“单元测试”。现在,我的完成块代码在作为单元测试运行时不会被调用。但是,当从AppDelegate
(didFinishWithLaunchingOptions) 中执行相同的代码时,会调用完成块中的代码。正如此线程中所建议的,NSURLSessionDataTask dataTaskWithURL 完成处理程序没有被调用,需要使用信号量和/或 dispatch_group “以确保主线程被阻塞,直到网络请求完成。”
我的 HTTP 邮政编码如下所示。
@interface LoginPost : NSObject
- (void) post;
@end
@implementation LoginPost
- (void) post
{
NSURLSessionConfiguration* conf = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession* session = [NSURLSession sessionWithConfiguration:conf delegate:nil delegateQueue:[NSOperationQueue mainQueue]];
NSURL* url = [NSURL URLWithString:@"http://www.example.com/login"];
NSString* params = @"username=test@xyz.com&password=test";
NSMutableRequest* request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSessionDataTask* task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(@"Response:%@ %@\n", response, error); //code here never gets called in unit tests, break point here never is triggered as well
//response is actually deserialized to custom object, code omitted
}];
[task resume];
}
@end
测试它的方法如下所示。
- (void) testPost
{
LoginPost* loginPost = [LoginPost alloc];
[loginPost post];
//XCTest continues by operating assertions on deserialized HTTP response
//code omitted
}
在我AppDelegate
的 中,完成块代码确实有效,如下所示。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//generated code
LoginPost* loginPost = [LoginPost alloc];
[loginPost post];
}
关于在单元测试中运行时如何执行完成块的任何指针?我是 iOS 的新手,所以一个清晰的例子真的很有帮助。
- 注意:我意识到我所要求的也可能不是严格意义上的“单元”测试,因为我依赖 HTTP 服务器作为测试的一部分(意思是,我所要求的更像是集成测试)。
- 注意:我意识到还有另一个线程Unit tests with NSURLSession关于使用 NSURLSession 进行单元测试,但我不想模拟响应。