I have been searching for a way to use SenTestingKit to do some integration testing between my client-side code and our server. I haven't had any luck. It seems that once the code is run in a method, the object gets destroyed. This means that any asynchronous responses never call the selectors.
Questions:
- Is there a way to keep the object instantiated until such time as I see fit to destroy it - ie. after the tests have completed?
- If not, how could I create a class that blocks (ie. acts synchronously) until the tests are completed?
FYI, I'm running a test server where I know the expected results.
I've done a fair bit of Googling but haven't seen proof one way or another about this. I'm sure others would be interested as well.
You can use a semaphore to wait until the asynchronous method finishes.
- (void)testBlockMethod {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
// Your block method eg. AFNetworking
NSURL *url = [NSURL URLWithString:@"http://httpbin.org/ip"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSLog(@"IP Address: %@", [JSON valueForKeyPath:@"origin"]);
STAssertNotNil(JSON, @"JSON not loaded");
// Signal that block has completed
dispatch_semaphore_signal(semaphore);
} failure:nil];
[operation start];
// Run loop
while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW))
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate dateWithTimeIntervalSinceNow:10]];
dispatch_release(semaphore);
}
http://samwize.com/2012/10/03/sentestingkit-does-not-support-wait-for-blocks/
Kiwi supports asynchronous testing. Kiwi is a Behavior Driven Development (BDD) library for iOS that extends SentTestingKit (OCUnit), so it's easy to set up & use.
Also, check out:
- iOS Tests/Specs TDD/BDD and Integration & Acceptance Testing.
- Testing asynchronous code on iOS with OCunit
This project https://github.com/hfossli/AGAsyncTestHelper has a very convenient macro
WAIT_WHILE(<expression_to_evaluate>, <max_duration>);
Which ables you to write the test like so
- (void)testDoSomething {
__block BOOL somethingIsDone = NO;
[MyObject doSomethingAsyncThenRunCompletionBlockOnMainQueue:^{
somethingIsDone = YES;
}];
WAIT_WHILE(!somethingIsDone, 1.0);
NSLog(@"This won't be reached until async job is done");
}
Checkout the SenTestingKitAsync project - https://github.com/nxtbgthng/SenTestingKitAsync. The related blog is here - http://www.objc.io/issue-2/async-testing.html