hasrthur
hasrthur

Reputation: 1490

How one tests http requests in iOS 8?

In ruby I used to test http requests with vcr gem which recorded the request so the tests didn't send request to real host. Is there anything like this in iOS8 world? The requests I want to test really need to be recorded since those requests may be outdated in some time and will return some other response

P.S. It would be great if it was some default Apple/iOS approach/library like XCTest for testing in general

Upvotes: 3

Views: 1127

Answers (2)

plluke
plluke

Reputation: 1905

What you want is something like OHHTTPStubs or Nocilla or AMY server. All of them essentially use NSURLProtocol to intercept your request and allow you to designate a response. We used OHHTTPStubs but pick the one with the feature set closest to your use case.

Here's an example of an OHHTTPStubs implementation in a unit test for a service that talks to a single REST endpoint:

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();
}];

In reality our tests are shorter since we write wrapper/helpers to make it read better so this is an exploded-out version. Should give you the general idea. OHHTTPStubs (if you use it) has helper functions to load responses directly from files as well.

Upvotes: 1

Christian
Christian

Reputation: 22343

Im not sure if I understood you correct. But if I understand you right, you should be able to use XCTest to test your request and response.

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)")
            }
        }

    }

}

Upvotes: 1

Related Questions