【发布时间】:2014-07-02 16:13:06
【问题描述】:
我想知道如何使用 NSURLSession 对 HTTP 请求和响应进行“单元测试”。现在,我的完成块代码在作为单元测试运行时不会被调用。但是,当从AppDelegate (didFinishWithLaunchingOptions) 中执行相同的代码时,会调用完成块内的代码。正如此线程 NSURLSessionDataTask dataTaskWithURL completion handler not getting called 中所建议的,需要使用信号量和/或 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 进行单元测试,但我不想模拟响应。
【问题讨论】:
-
与您的原始问题无关,在构建您的
POST请求时,我建议对值进行百分比转义(如果用户名或密码具有保留字符,例如+或&,这是行不通的)。此外,将Content-type标头设置为application/x-www-form-urlencoded可能是一个好习惯。但也许你只是想把我们从那些血淋淋的细节中解脱出来。 :)
标签: ios objective-c nsurlsession xctest nsurlsessiontask