Several things to comment about your question.
First of all, your code is hard to test because it is creating the AFHTTPClient directly. I don't know if it's because it's just a sample, but you should inject it instead (see the sample below).
Second, you are creating the request, then the AFHTTPRequestOperation and then you enqueue it. This is fine but you can get the same using the AFHTTPClient method getPath:parameters:success:failure:.
I do not have experience with that suggested HTTP stubbing tool (Nocilla) but I see it is based on NSURLProtocol. I know some people use this approach but I prefer to create my own stubbed response objects and mock the http client like you see in the following code.
Retriever is the class we want to test where we inject the AFHTTPClient.
Note that I am passing directly the user and event id, since I want to keep things simple and easy to test. Then in other place you would pass the accout uid value to this method and so on...
The header file would look similar to this:
#import <Foundation/Foundation.h>
@class AFHTTPClient;
@protocol RetrieverDelegate;
@interface Retriever : NSObject
- (id)initWithHTTPClient:(AFHTTPClient *)httpClient;
@property (readonly, strong, nonatomic) AFHTTPClient *httpClient;
@property (weak, nonatomic) id<RetrieverDelegate> delegate;
- (void) retrieveEventWithUserId:(NSString *)userId eventId:(NSString *)eventId;
@end
@protocol RetrieverDelegate <NSObject>
- (void) retriever:(Retriever *)retriever didFindEvenData:(NSDictionary *)eventData;
@end
Implementation file:
#import "Retriever.h"
#import <AFNetworking/AFNetworking.h>
@implementation Retriever
- (id)initWithHTTPClient:(AFHTTPClient *)httpClient
{
NSParameterAssert(httpClient != nil);
self = [super init];
if (self)
{
_httpClient = httpClient;
}
return self;
}
- (void)retrieveEventWithUserId:(NSString *)userId eventId:(NSString *)eventId
{
NSString *path = [NSString stringWithFormat:@"/user/%@/event/%@", userId, eventId];
[_httpClient getPath:path
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSDictionary *eventData = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:NULL];
if (eventData != nil)
{
[self.delegate retriever:self didFindEventData:eventData];
}
}
failure:nil];
}
@end
And the test:
#import <XCTest/XCTest.h>
#import "Retriever.h"
// Collaborators
#import <AFNetworking/AFNetworking.h>
// Test support
#import <OCMock/OCMock.h>
@interface RetrieverTests : XCTestCase
@end
@implementation RetrieverTests
- (void)setUp
{
[super setUp];
// Put setup code here; it will be run once, before the first test case.
}
- (void)tearDown
{
// Put teardown code here; it will be run once, after the last test case.
[super tearDown];
}
- (void) test__retrieveEventWithUserIdEventId__when_the_request_and_the_JSON_parsing_succeed__it_calls_didFindEventData
{
// Creating the mocks and the retriever can be placed in the setUp method.
id mockHTTPClient = [OCMockObject mockForClass:[AFHTTPClient class]];
Retriever *retriever = [[Retriever alloc] initWithHTTPClient:mockHTTPClient];
id mockDelegate = [OCMockObject mockForProtocol:@protocol(RetrieverDelegate)];
retriever.delegate = mockDelegate;
[[mockHTTPClient expect] getPath:@"/user/testUserId/event/testEventId"
parameters:nil
success:[OCMArg checkWithBlock:^BOOL(void (^successBlock)(AFHTTPRequestOperation *, id))
{
// Here we capture the success block and execute it with a stubbed response.
NSString *jsonString = @"{\"some valid JSON\": \"some value\"}";
NSData *responseObject = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
[[mockDelegate expect] retriever:retriever didFindEventData:@{@"some valid JSON": @"some value"}];
successBlock(nil, responseObject);
[mockDelegate verify];
return YES;
}]
failure:OCMOCK_ANY];
// Method to test
[retriever retrieveEventWithUserId:@"testUserId" eventId:@"testEventId"];
[mockHTTPClient verify];
}
@end
The last thing to comment is that the AFNetworking 2.0 version is released so consider using it if it covers your requirements.
NSURLConnections
and define their behavior. – Spot