-
-
Save appcoders/e3850c2c81f9c1339588bdeb077c9098 to your computer and use it in GitHub Desktop.
A primer for testing asynchronous calls with XCTest in Objective-C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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