I have a unit test in which I need to wait for an async task to finish. I am trying to use NSConditionLock as it seems to be a pretty clean solution but I cannot get it to work.
Some test code:
- (void)testSuccess
{
loginLock = [[NSConditionLock alloc] init];
Login login = [[Login alloc] init];
login.delegate = self;
// The login method will make an async call.
// I have setup myself as the delegate.
// I would like to wait to the delegate method to get called
// before my test finishes
[login login];
// try to lock to wait for delegate to get called
[loginLock lockWhenCondition:1];
// At this point I can do some verification
NSLog(@"Done running login test");
}
// delegate method that gets called after login success
- (void) loginSuccess {
NSLog(@"login success");
// Cool the delegate was called this should let the test continue
[loginLock unlockWithCondition:1];
}
I was trying to follow the solution here: How to unit test asynchronous APIs?
My delegate never gets called if I lock. If I take out the lock code and put in a simple timer it works fine.
Am I locking the entire thread and not letting the login code run and actually make the async call?
I also tried this to put the login call on a different thread so it does not get locked.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
[login login];
});
What am I doing wrong?
EDIT adding login code. Trimmed do the code for readability sake. Basically just use AFNetworking to execute a POST. When done will call delegate methods. Login make a http request:
NSString *url = [NSString stringWithFormat:@"%@/%@", [_baseURL absoluteString], @"api/login"];
[manager POST:url parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
if (_delegate) {
[_delegate loginSuccess];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (_delegate) {
[_delegate loginFailure];
}
}];
The answer can be found in https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFHTTPRequestOperation.m.
Since you are not setting the
completionQueue
property of the implicitly createdAFHTTPRequestOperation
, it is scheduling the callbacks on the main queue, which you are blocking.