简体   繁体   English

在iOS单元测试中模拟NSHTTPURLRequest和NSHTTPURLResponse

[英]Mock NSHTTPURLRequest and NSHTTPURLResponse in iOS unit test

我正在iOS中开发一个框架,它对服务器进行HTTP调用。我想编写单元测试来测试API。我想模拟服务器调用,而不是实际调用真正的服务器。任何人都可以帮我进行样本单元测试制作模拟服务器调用。如何设置期望并返回手工构建的url响应。我使用XCTest框架进行单元测试,使用OCMock进行模拟对象。

Here is how you might mock sendAsynchronousRequest: 您可以通过以下方式模拟sendAsynchronousRequest:

NSDictionary *serverResponse = @{ @"response" : [[NSHTTPURLResponse alloc] initWithURL:nil statusCode:200 HTTPVersion:nil headerFields:@{}],
                                  @"data" : [@"SOMEDATA" dataUsingEncoding:NSUTF8StringEncoding]
                                  };

id connectionMock = [OCMockObject mockForClass:NSURLConnection.class];
[[[connectionMock expect] andDo:^(NSInvocation *invocation) {
    void (^handler)(NSURLResponse*, NSData*, NSError*);
    handler = [invocation getArgumentAtIndexAsObject:4];
    handler(serverResponse[@"response"], serverResponse[@"data"], serverResponse[@"error"]);
}] sendAsynchronousRequest:OCMOCK_ANY queue:OCMOCK_ANY completionHandler:OCMOCK_ANY];

EDIT 编辑

To add clarification, here's what's happening. 为了补充说明,这是正在发生的事情。 In this example our real code is calling [NSURLConnection sendAsynchronousRequest: queue: completionHandler:] There are three arguments passed to this method, plus the additional _cmd and self that is passed to all Objective-C method calls. 在这个例子中,我们的实际代码是调用[NSURLConnection sendAsynchronousRequest: queue: completionHandler:]传递给此方法的三个参数,以及传递给所有Objective-C方法调用的附加_cmdself Thus when we examine our NSInvocation the argument at index 4 is our completion handler. 因此,当我们检查NSInvocation ,索引4处的参数是我们的完成处理程序。 Since we are simulating the response from the server, we want to call this handler with fake data that represents the case we are testing. 由于我们正在模拟来自服务器的响应,因此我们希望使用表示我们正在测试的案例的假数据来调用此处理程序。

The signature for the method call getArgumentAtIndexAsObject is in a header file included with OCMock, but is not included by default in the framework. 方法调用getArgumentAtIndexAsObject的签名位于getArgumentAtIndexAsObject附带的头文件中,但默认情况下不包含在框架中。 I believe it is called NSInvocation+OCMAdditions.h . 我相信它被称为NSInvocation+OCMAdditions.h It makes fetching the invocation arguments easier by returning an id . 它通过返回id使得更容易获取调用参数。

Use OHTTPStubs, https://github.com/AliSoftware/OHHTTPStubs . 使用OHTTPStubs, https://github.com/AliSoftware/OHHTTPStubs

Here's a practical example of mocking the response to a specific GET request and returning JSON data. 这是一个模拟对特定GET请求的响应并返回JSON数据的实际示例。

[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) {
    return [request.URL.path isEqualToString:@"/api/widget"];
} withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) {
    id JSON = @{ @"id": @"1234", @"name" : @"gadget" };
    NSData *data = [NSJSONSerialization dataWithJSONObject:JSON options:0 error:nil];
    return [OHHTTPStubsResponse responseWithData:data statusCode:200 headers:@{ @"Content-Type": @"application/json" }];
}];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM