I\'m working on an iOS app whose primary purpose is communication with a set of remote webservices. For integration testing, I\'d like to be able to run my app against some sort
You can make a mock web service quite effectively with a NSURLProtocol subclass:
Header:
@interface MyMockWebServiceURLProtocol : NSURLProtocol
@end
Implementation:
@implementation MyMockWebServiceURLProtocol
+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
return [[[request URL] scheme] isEqualToString:@"mymock"];
}
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request
{
return request;
}
+ (BOOL)requestIsCacheEquivalent:(NSURLRequest *)a toRequest:(NSURLRequest *)b
{
return [[a URL] isEqual:[b URL]];
}
- (void)startLoading
{
NSURLRequest *request = [self request];
id client = [self client];
NSURL *url = request.URL;
NSString *host = url.host;
NSString *path = url.path;
NSString *mockResultPath = nil;
/* set mockResultPath here … */
NSString *fileURL = [[NSBundle mainBundle] URLForResource:mockResultPath withExtension:nil];
[client URLProtocol:self
wasRedirectedToRequest:[NSURLRequest requestWithURL:fileURL]
redirectResponse:[[NSURLResponse alloc] initWithURL:url
MIMEType:@"application/json"
expectedContentLength:0
textEncodingName:nil]];
[client URLProtocolDidFinishLoading:self];
}
- (void)stopLoading
{
}
@end
The interesting routine is -startLoading, in which you should process the request and locate the static file corresponding to the response in the app bundle before redirecting the client to that file URL.
You install the protocol with
[NSURLProtocol registerClass:[MyMockWebServiceURLProtocol class]];
And reference it with URLs like
mymock://mockhost/mockpath?mockquery
This is considerably simpler than implementing a real webservice either on a remote machine or locally within the app; the tradeoff is that simulating HTTP response headers is much more difficult.