如何在 iOS 8 中测试 http 请求?
How one tests http requests in iOS 8?
在 ruby 中,我曾经使用记录请求的 vcr gem 测试 http 请求,因此测试不会向真实主机发送请求。 iOS8世界上有这样的东西吗?
我想测试的请求确实需要记录下来,因为这些请求可能会在一段时间内过时,并且 return 一些其他响应
P.S。如果它是一些默认的 Apple/iOS approach/library 就像用于一般测试的 XCTest
那样就好了
我不确定我是否理解正确。但是如果我没理解错的话,你应该可以使用 XCTest
来测试你的请求和响应。
class Tests:XCTestCase{
func testing(){
var expectation = self.expectationWithDescription("Your request")
var url = NSURL(string: "http://yourUrl.com")
let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in
if let httpRes = response as? NSHTTPURLResponse {
println("status code=",httpRes.statusCode)
//200 means OK
if httpRes.statusCode == 200 {
println(NSString(data: data, encoding: NSUTF8StringEncoding))
}
}else{
println("error \(error)")
}
}
}
}
您想要的是 OHHTTPStubs 或 Nocilla 或 AMY 服务器之类的东西。它们基本上都使用 NSURLProtocol 来拦截您的请求并允许您指定响应。我们使用了 OHHTTPStubs,但选择了功能集最接近您的用例的那个。
下面是与单个 REST 端点通信的服务的单元测试中的 OHHTTPStubs 实现示例:
NSString *loadRoomJSON = @{ @"key" : @"value" }; /* some JSON */
NSNumber identifier = @1;
[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) {
NSString *url = [NSString stringWithFormat:@"v1/user/%@/room", identifier];
XCTAssert([request.URL.relativePath containsString:url], @"Expected certain URL");
return YES;
} andRespond:^OHHTTPStubsResponse *(NSURLRequest *request) {
return [OHHTTPStubsResponse responseWithJSONObject:loadRoomJSON statusCode:200 headers:nil];
}];
XCTestExpectation *loadPromise = [self expectation:@"Room loaded"];
[service loadRoomOnSucceed:^(Room *room) {
// Do your asserts here. For us, the JSON is mapped to an object
// so for example you could assert that the object is mapped correctly
[loadPromise fulfill];
} onFail:^(NSError *error) {
expect(error).to.beNil();
}];
[self waitForExpectationsWithTimeout:1.0 handler:^(NSError *error) {
expect(error).to.beNil();
}];
实际上我们的测试更短,因为我们编写 wrapper/helpers 是为了让它更容易阅读,所以这是一个展开的版本。应该给你大概的想法。 OHHTTPStubs(如果你使用的话)也有帮助函数来直接从文件加载响应。
在 ruby 中,我曾经使用记录请求的 vcr gem 测试 http 请求,因此测试不会向真实主机发送请求。 iOS8世界上有这样的东西吗? 我想测试的请求确实需要记录下来,因为这些请求可能会在一段时间内过时,并且 return 一些其他响应
P.S。如果它是一些默认的 Apple/iOS approach/library 就像用于一般测试的 XCTest
那样就好了我不确定我是否理解正确。但是如果我没理解错的话,你应该可以使用 XCTest
来测试你的请求和响应。
class Tests:XCTestCase{
func testing(){
var expectation = self.expectationWithDescription("Your request")
var url = NSURL(string: "http://yourUrl.com")
let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in
if let httpRes = response as? NSHTTPURLResponse {
println("status code=",httpRes.statusCode)
//200 means OK
if httpRes.statusCode == 200 {
println(NSString(data: data, encoding: NSUTF8StringEncoding))
}
}else{
println("error \(error)")
}
}
}
}
您想要的是 OHHTTPStubs 或 Nocilla 或 AMY 服务器之类的东西。它们基本上都使用 NSURLProtocol 来拦截您的请求并允许您指定响应。我们使用了 OHHTTPStubs,但选择了功能集最接近您的用例的那个。
下面是与单个 REST 端点通信的服务的单元测试中的 OHHTTPStubs 实现示例:
NSString *loadRoomJSON = @{ @"key" : @"value" }; /* some JSON */
NSNumber identifier = @1;
[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) {
NSString *url = [NSString stringWithFormat:@"v1/user/%@/room", identifier];
XCTAssert([request.URL.relativePath containsString:url], @"Expected certain URL");
return YES;
} andRespond:^OHHTTPStubsResponse *(NSURLRequest *request) {
return [OHHTTPStubsResponse responseWithJSONObject:loadRoomJSON statusCode:200 headers:nil];
}];
XCTestExpectation *loadPromise = [self expectation:@"Room loaded"];
[service loadRoomOnSucceed:^(Room *room) {
// Do your asserts here. For us, the JSON is mapped to an object
// so for example you could assert that the object is mapped correctly
[loadPromise fulfill];
} onFail:^(NSError *error) {
expect(error).to.beNil();
}];
[self waitForExpectationsWithTimeout:1.0 handler:^(NSError *error) {
expect(error).to.beNil();
}];
实际上我们的测试更短,因为我们编写 wrapper/helpers 是为了让它更容易阅读,所以这是一个展开的版本。应该给你大概的想法。 OHHTTPStubs(如果你使用的话)也有帮助函数来直接从文件加载响应。