-
Notifications
You must be signed in to change notification settings - Fork 599
Testing for the request body in your stubs
As seen in issue #52, unfortunately when you send POST requests (with a body) using NSURLSession, by the time the request arrives to OHHTTPStubs, the HTTPBody of the NSURLRequest can't be accessed anymore (probably already transformed internally to an HTTPBodyStream?).
Therefore, you cannot directly test the request.HTTPBody in your [OHHTTPStubs stubRequestsPassingTest:withStubResponse:] as the HTTPBody property will return nil at that time.
A nice workaround is to use [NSURLProtocol setProperty:forKey:inRequest:], which allows you to associate arbitrary key/value pairs to your NSURLRequests that you can later query using [NSURLProtocol propertyForKey:inRequest:].
Thus you can easily use this method to store the request body, or the parameters dictionary used to build the query part of your GET URLs or the body of your POST request, or the RPC method that your request intends to call, or whatnot, alongside your request. And use it to conditionally stub your requests then.
If you are using AFNetworking 2.0+ to build your request, you can provide a custom AFHTTPRequestSerializer class to associate some properties to your requests when building them.
Here is an example on how to do that to automatically associate the parameters and body to each request build using the RequestSerializer.
@interface AnnotatedRequestSerializer : AFHTTPRequestSerializer @end
@implementation AnnotatedRequestSerializer
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
URLString:(NSString *)URLString
parameters:(NSDictionary *)parameters
error:(NSError * __autoreleasing *)error
{
NSMutableURLRequest* req = [super requestWithMethod:method URLString:URLString parameters:parameters error:error];
[NSURLProtocol setProperty:parameters forKey:@"parameters" inRequest:req];
[NSURLProtocol setProperty:req.HTTPBody forKey:@"HTTPBody" inRequest:req];
return req;
}
@end
sessionMgr = [[AFHTTPSessionManager alloc] initWithBaseURL:… sessionConfiguration:…];
sessionMgr.requestSerializer = [AnnotatedRequestSerializer serializer];
[sessionMgr POST:@"/login"
parameters:@{ @"login":@"foo", @"password":@"bar" }
success:…
failure:…
];
[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) {
NSDictionary* requestParams = [NSURLProtocol propertyForKey:@"parameters" inRequest:request];
// You could also query the request body if needed using the associated property too:
// NSData* requestBody = [NSURLProtocol propertyForKey:@"HTTPBody" inRequest:request];
// NSString* bodyString = [[NSString alloc] initWithData:requestBody encoding:NSUTF8StringEncoding];
// Only stub POST requests to "/login" with "user" = "foo" & "password" = "bar"
return [request.HTTPMethod isEqualToString:@"POST"]
&& [request.URL.path isEqualToString:@"/login"]
&& [requestParams[@"user"] isEqualToString:@"foo"]
&& [requestParams[@"password"] isEqualToString:@"bar"];
} withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) {
return [OHHTTPStubsResponse responseWithData:validLoginResponseData statusCode:200 headers:headers];
}].name = @"login";