Create Async Test With GHUnit

One of the greatest feature with GHUnit is that it supports unit tests that perform asynchronous stuff.

The ExampleAsyncTest from GHUnit documentation provides a glimpse of what you need to do. However, it still lacks warning you on the common pitfalls.

This is step by step of how you can use GHUnit async test:

Subclass GHAsyncTestCase instead

Change the interface class to use GHAsyncTestCase.

1
2
@interface ExampleAsyncTest : GHAsyncTestCase { }
@end

Prepare and wait

Setup the test method with the asynchronous/block call like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
- (void)testAsync {
    // Prepare asynchronous action
    [self prepare];

    // The method call with block
    static NSArray *_objects;
    [Query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        // IMPORTANT: Do not call any assert here
        // If you want, do it after waitForStatus
        // GHAssertEquals(...) will crash!

        // Instead, we assign to a static var for testing later
        _objects = objects;

        // Notify that block method has completed
        [self notify:kGHUnitWaitStatusSuccess forSelector:@selector(testObjectRelationships)];
    }];

    // Wait for block to finish, or timeout
    [self waitForStatus:kGHUnitWaitStatusSuccess timeout:10.0];

    // Do asserts here instead
    GHAssertEquals(99U, [_objects count], nil);
}

Pitfall: Assert in block

It is common that you assert within the block.

But that will just give the following exception when the test fails.

Terminating app due to uncaught exception 'GHTestFailureException', reason: ...

To make it work, you don’t call any asserts within the block.

Leave it until waitForStatus is unblocked.

Comments