Reputation: 965
I'm trying to test the URL/path against a request is (or would be) made from a REST-client class using OCMock. The client uses RestKit (which uses AFNetworking) for the communication. Therefore my plan was to:
AFHTTPRequestOperation
URL is the desired one.AFHTTPClient
.enqueueHTTPRequestOperation:
method with the block (of 1.).RKObjectManager
and set its HTTPClient
property to the
AFHTTPClient
partial-mock (of 2.).enqueueHTTPRequestOperation:
was invoked.I'm not sure if I'm getting OCMock wrong because I couldn't find examples on mocking methods that take one or more arguments like I need to. ...never the less, this is how I tried to achieve the goal:
void (^checkBlock)(NSInvocation *) = ^(NSInvocation *invocation) {
AFHTTPRequestOperation *requestOperation = nil;
[invocation getArgument:&requestOperation atIndex:0];
XCTAssert(requestOperation != nil);
NSString *path = requestOperation.request.URL.path;
XCTAssert([path containsString:@"/rest/user/authenticate"]);
};
AFHTTPClient *httpClientMock = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:FAServerUrl]];
OCMPartialMock(httpClientMock);
[OCMStub([httpClientMock enqueueHTTPRequestOperation:[OCMArg isNotNil]]) andDo:checkBlock];
RKObjectManager *objectManager = OCMClassMock([RKObjectManager class]);
[OCMStub([objectManager HTTPClient]) andReturn:httpClientMock];
FAUserClient *userClient = [[FAUserClient alloc] initWithUser:nil objectManager:objectManager];
[userClient getAccessTokenForUsername:@"testuser"
password:@"pass123"
success:^(NSString *token, NSArray *roles) {
}
failure:^(NSInteger errorCode, NSError *error) {
}];
OCMVerify([httpClientMock enqueueHTTPRequestOperation:OCMOCK_ANY]);
But on [OCMStub([httpClientMock enqueueHTTPRequestOperation:[OCMArg isNotNil]]) andDo:checkBlock];
I get an EXC_BAD_ACCESS (code=1).
Apparently creating the mock-stub (with OCMStub
) invokes the to be stubbed method, with the given [OCMArg isNotNil]
. I thought A: the parameter just has a declarative meaning and B: this creates a stub and does not invoke the method right away.
Any help or suggestions leading into the "right" direction would be greatly appreciated.
EDIT:
As well tried:
OCMStub([httpClientMock enqueueHTTPRequestOperation:[OCMArg checkWithBlock:^BOOL(id obj) {
AFHTTPRequestOperation *request = (AFHTTPRequestOperation *)obj;
NSString *path = request.request.URL.path;
XCTAssert([path containsString:@"/rest/user/authenticate"]);
return YES;
}]]);
...with the same "result".
Best, gabriel
Upvotes: 0
Views: 825
Reputation: 18922
Edit
Looked more closely. You are calling OCMPartialMock(httpClientMock)
. This does not convert the object you call it on, it returns a partial mock. Capture the result in a variable.
AFHTTPClient *httpClientMock = OCPartialMock([[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:FAServerUrl]]);
You should still make the change noted below in your andDo:
block. You can also use the "modern" syntax for this:
OCMStub([myObject myMethod]).andDo(myBlock);
Original
I think the issue might be the code in the andDo:
block.
[invocation getArgument:&requestOperation atIndex:0];
For all Objective-C methods, NSInvocation has two default arguments, self
and _cmd
at indexes 0 and 1. Try getting the argument at index 2.
You might also consider including NSInvocation+OCMAdditions which gives you getArgumentAtIndexAsObject
. Another alternative is using [OCMArg checkWithBlock:]
in which the arg is handed to your evaluation block directly.
Upvotes: 1