Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save GrigoriiVakhmistrov/3b8c5b1a378a6e096d5dc4c104d485b9 to your computer and use it in GitHub Desktop.
Save GrigoriiVakhmistrov/3b8c5b1a378a6e096d5dc4c104d485b9 to your computer and use it in GitHub Desktop.
A primer for testing asynchronous calls with XCTest in Objective-C
#import <XCTest/XCTest.h>
@interface AsyncTestingPrimer : XCTestCase
@end
@implementation AsyncTestingPrimer
/*
* This is how not to test async calls
*/
- (void) testBrokenAsync {
__block BOOL isTouched = false;
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
// Wait for half a second before doing anything, make sure we're pre-empted
[NSThread sleepForTimeInterval:0.5];
isTouched = true;
});
XCTAssert(isTouched, @"This fails because the async block has not completed yet.");
}
/*
* Let's try again, using test expectations
*/
- (void) testAsyncWithExpectations {
__block BOOL isTouchedWithExpectations = false;
XCTestExpectation *myExpectation = [self expectationWithDescription:@"Expectation for the following async block"];
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
[NSThread sleepForTimeInterval:0.5];
isTouchedWithExpectations = true;
// Let anyone who's waiting know we're done
[myExpectation fulfill];
});
// Wait for all expectations to be fulfilled.
[self waitForExpectationsWithTimeout:1 handler:nil];
XCTAssert(isTouchedWithExpectations, @"This succeeds because we waited for the expectation fulfilment in the async block");
}
/*
* But make sure all your expectations are fulfilled, otherwise you will time out.
*/
- (void) testAsyncWithTooManyExpectations {
__block BOOL isTouchedWithExpectations = false;
XCTestExpectation *myExpectation = [self expectationWithDescription:@"Expectation for the following async block"];
XCTestExpectation *excessExpectation = [self expectationWithDescription:@"This expectation will never be fulfilled"];
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
[NSThread sleepForTimeInterval:0.5];
isTouchedWithExpectations = true;
// Let anyone who's waiting know we're done
[myExpectation fulfill];
});
// Wait for all expectations to be fulfilled.
[self waitForExpectationsWithTimeout:1 handler:nil];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment