Skip to content

Instantly share code, notes, and snippets.

@AliSoftware
Last active December 25, 2015 06:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AliSoftware/6934902 to your computer and use it in GitHub Desktop.
Save AliSoftware/6934902 to your computer and use it in GitHub Desktop.
Demo of code executing even after a unit test has finished
- (void)setUp
{
[super setUp];
[MagicalRecord setupCoreDataStackWithInMemoryStore];
}
- (void)tearDown
{
[MagicalRecord cleanUp]; // cleans up the CoreData stack to be ready for a clean state for the next tests
// Note: any code after this line that would try to use CoreData will obviously fail
[super tearDown];
}
- (void)testFoo
{
__block BOOL _done = NO;
[self doSomeLongTaskWithCompletion:^{
[[NSManagedObjectContext defaultContext] save:nil]; // Do some CoreData stuff here
_done = YES;
}];
NSDate* timeoutDate = [NSDate dateWithTimeIntervalSinceNow:3];
while (!_done && ([timeoutDate timeIntervalSinceNow]>0))
{
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.01, YES);
}
STAssertTrue(_done, @"Test timed out");
}
- (void)doSomeLongTaskWithCompletion:(dispatch_block_t)completion
{
// Some long task
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
sleep(5); // imagine this is a long task
completion();
});
}
/* The problem:
- The test will time out after 3 seconds, so before the "doSomeLonTaskWithCompletion:" method completes.
- The test will then fail, and the -tearDown method will be called… cleaning the CoreData stack
- But 2s later, the completion block will still be called, (even if the test is finised, the long method was still running) and will call its CoreData stuff but the CoreData stack was already cleaned up by 'tearDown'! So this will crash.
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment