Can't get OHHTTPStubs to work with NSURLSession

2.3k Views Asked by At

I'm trying to use OHHTTPStubs in my XCTest class,

This is how I configured OHTTPStubs in my test file.

//
// Tests Configuration
//
- (void)setUp
{
    [super setUp];
    _bundle = [NSBundle bundleForClass:[self class]];
    [self configureHTTPStubs];
    [self installHTTPStubs];
}

- (void)configureHTTPStubs
{
    [OHHTTPStubs onStubActivation:^(NSURLRequest *request, id<OHHTTPStubsDescriptor> stub) {
        NSLog(@"[OHHTTPStubs] Request to %@ has been stubbed with %@", request.URL, stub.name);
    }];
}

- (void)installHTTPStubs
{
    HIAPIRequests *requester = [[HIAPIOperator sharedOperator] requester];
    [OHHTTPStubs setEnabled:YES forSessionConfiguration:requester.session.configuration];
    [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) {
        return [request.URL.path isEqualToString:@"/image_upload"];
    } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) {
        return [[OHHTTPStubsResponse responseWithFileAtPath:OHPathForFileInBundle(@"image_upload_ws_response.json", nil)
                                                 statusCode:201
                                                    headers:@{@"Content-Type":@"text/json"}] responseTime:OHHTTPStubsDownloadSpeed3G];
    }].name = @"Image Upload OK";

}

//
// In my Requester class this is how I setup the NSURLSession configuration
//
- (void)configureURLSession
{
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    _session = [NSURLSession sessionWithConfiguration:config];
}

And this is how I'm performing a request

- (void)uploadImage:(UIImage *)image
    completionBlock:(operationCompletionBlock)completionBlock
      progressBlock:(operationProgressBlock)progressBlock
{
    NSData *imageData = UIImageJPEGRepresentation(image, 0.80);
    NSURLRequest *request = [NSURLRequest requestWithURLString:@"/image_upload"];
    NSURLSessionUploadTask *uploadTask = [_session uploadTaskWithRequest:request
                                                            fromData:imageData
                                                   completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                       completionBlock(data, error);
                                                   }];

    [_progressTable setObject:progressBlock forKey:uploadTask];
    [uploadTask resume];
}

In the completionHandler callback I'm basically getting a no domain found error (error NSURLError * domain: @"NSURLErrorDomain" - code: -1003 0x08a70740) , @"A server with the specified hostname could not be found."

I'm completely sure that I'm querying the correct URL (the one I stubbed with OHHTTPStubs) in my test.

What could be going on here? Bug maybe?

1

There are 1 best solutions below

0
On BEST ANSWER

@Goles I know we already discussed that directly on the related issue you created on my GitHub, but I'm answering it here to so that other SO readers can have the solution too.

The issue in @Goles ' code is that he uses [OHHTTPStubs setEnabled:YES forSessionConfiguration:requester.session.configuration]; on an NSURLSessionConfiguration that was already used to create its NSURLSession.

As the Apple documentation explains, you can't modify an NSURLSessionConfiguration once it has been used to create an NSURLSession. Well, you can, but it won't have any effect on the already-created NSURLSession. If you modify an NSURLSessionConfiguration, you will have to create a new NSURLSession with that modified NSURLSessionConfiguration to take the new configuration into account.


Moreover, in the latest versions of OHHTTPStubs, it is not necessary anymore to explicitly call +[setEnabled:forSessionConfiguration:]: as explained in the documentation, every NSURLSessionConfiguration created with defaultSessionConfiguration or ephemeralSessionConfiguration will automatically have OHHTTPStubs enabled on them if you use my library.

This means that you don't need to change anything in your working code for your stubs to hook into your sessions and network requests (even if you create the NSURLSessionConfiguration and NSURLSession somewhere deeply hidden in your app code).


For those of you who want to use OHHTTPStubs with NSURLSession I strongly recommend to use the latest 3.0.2 version of OHHTTPStubs. NSURLSession support was indeed introduced in version 2.4.0 of OHHTTPStubs, but there were some glitches left in that version that have been fixed in version 3.x since.