Asynchronous Testing

Dave Meehan edited this page Oct 22, 2013 · 9 revisions

Specs | Expectations | Mocks and Stubs | Asynchronous Testing

It's very common for iOS applications to have components that collaborate with the main thread via background threads. Towards this end, Kiwi supports asynchronous testing, thus enabling integration tests - testing multiple objects collaborating together.

expectFutureValue() and shouldEventually

To setup an asynchronous expectation, you must wrap the subject in expectFutureValue and use the shouldEventually or shouldEventuallyBeforeTimingOutAfter verifiers.

shouldEventually waits for 1 second by default before failing the test.

[[expectFutureValue(myObject) shouldEventually] beNonNil];

With Scalars

That includes when you have scalars as the subject - wrap theValue in expectFutureValue, for example:

[[expectFutureValue(theValue(myBool)) shouldEventually] beYes];

shouldEventuallyBeforeTimingOutAfter()

This blocks for two seconds instead of the default one second.

[[expectFutureValue(fetchedData) shouldEventuallyBeforeTimingOutAfter(2.0)] equal:@"expected response data"];

Inverse

There are also shouldNotEventually and shouldNotEventuallyBeforeTimingOutAfter variants.

An example, using LRResty library:

This will block until the matcher is satisfied or it times out (default: 1s)

    context(@"Fetching service data", ^{
        it(@"should receive data within one second", ^{

            __block NSString *fetchedData = nil;

            [[LRResty client] get:@"http://www.example.com" withBlock:^(LRRestyResponse* r) {
                NSLog(@"That's it! %@", [r asString]);
                fetchedData = [r asString];
            }];

            [[expectFutureValue(fetchedData) shouldEventually] beNonNil];

        });

    });