Search code examples
iosobjective-cunit-testingafnetworkingafnetworking-2

AFNetworking 2.0: Subclassing AFHTTPSessionManager for TDD causing error in AFURLRequestSerialization init


I've subclassed AFHTTPSessionManager in order to make a mock out of it to use while testing. However, I keep running into a BAD_ACCESS error in AFURLRequestSerialization's init method - only with the mock. Here's the setup:

Testing class:

@interface PLBookCommunicatorTests : XCTestCase
@end

@implementation PLBookCommunicatorTests
{
    MockAFHTTPSessionManager *httpSessionManager;
    HKCommunicator *communicator;
}

- (void)setUp
{
     [super setUp];

     httpSessionManager = [[MockAFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:@"http://base.url"]];

     communicator = [[HKCommunicator alloc] initWithHttpSessionManager:httpSessionManager];
}

MockAFHTTPSessionMannager.h

#import "AFHTTPSessionManager.h"

@interface MockAFHTTPSessionManager : AFHTTPSessionManager

@property (nonatomic, assign) BOOL successful;

@end

MockAFHTTPSessionManager.m

import <AFNetworking.h>
#import "MockAFHTTPSessionManager.h"

@implementation MockAFHTTPSessionManager

- (NSURLSessionDataTask *)GET:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *, id))success failure:(void (^)(NSURLSessionDataTask *, NSError *))failure
{
    if(self.successful)
    {
        success(nil, nil);
    }
    else
    {
        failure(nil, nil);
    }

    return nil;
}

@end

I run into an error in this portion of AFURLRequestSerialization's init method:

self.mutableObservedChangedKeyPaths = [NSMutableSet set];
for (NSString *keyPath in AFHTTPRequestSerializerObservedKeyPaths()) {
    if ([self respondsToSelector:NSSelectorFromString(keyPath)]) {
        [self addObserver:self forKeyPath:keyPath    options:NSKeyValueObservingOptionNew     context:AFHTTPRequestSerializerObserverContext];
    }
}

Specifically, at the [self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:AFHTTPRequestSerializerObserverContext]; line. It catches on the very first run of that for loop

I'm not understanding why that line catches only in my mock. Is there something I'm missing while subclassing AFHTTPSessionManager? Perhaps something to do with the addObserver method?


Solution

  • This issue was fixed shortly after in release 2.5.1 of AFNetworking: https://github.com/AFNetworking/AFNetworking/releases/tag/2.5.1