Last Updated: February 25, 2016
·
2.728K
· raphaeloliveira

How to unit test blocks in Obj-C

Unit tests in Objective-C using the default test framework will not wait for a inline block to be executed. But them, how to test blocks? Use this trick below!

#define TestNeedsToWaitForBlock() __block BOOL blockFinished = NO
#define BlockFinished() blockFinished = YES
#define WaitForBlock() while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) && !blockFinished)

Example:

- (void)testWaitForBlock {
    TestNeedsToWaitForBlock();

    [target selectorWithInlineBlock:^(id obj) {

        // assertions

        BlockFinished();
    }];

    WaitForBlock();
}

2 Responses
Add your response

Just use a semaphore.

- (void)testWaitForBlock {
     dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
     [target selectorWithInlineBlock:^(id obj) {
        // Assertions
        dispatch_semaphore_signal(semaphore);
    }];

    while(dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW))
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:TIMEOUT];
}

Just make sure to define TIMEOUT to some number of seconds you're willing to wait before timing out.

Also none of this is needed if this "inline block" is executed synchronously on the same thread that called the method it was passed to before that method exits. I.e., the block evaluation blocks the method return until the block returns at least.

over 1 year ago ·

Great solution too! Thanks!

over 1 year ago ·