Skip to content

Instantly share code, notes, and snippets.

@aquarius
Created July 30, 2013 12:15
Show Gist options
  • Save aquarius/6112410 to your computer and use it in GitHub Desktop.
Save aquarius/6112410 to your computer and use it in GitHub Desktop.
Usage:
- (void)testCreateNewDocument
{
[self mn_preformWithTimeout:10 asynchronousTest:^{
[[MNDocumentController sharedDocumentController] createNewDocumentInFolder:nil withCompletionHandler:^(MNDocument *document, MNDocumentReference *reference) {
XCTAssertTrue(document && reference, @"Failed to create document.");
[self mn_finishRunningAsynchronousTest];
}];
}];
}
//
// XCTestCase+MNAsynchronousTestCase.h
// MindNodeTouch
//
// Created by Markus Müller-Simhofer on 28.07.13.
// Copyright (c) 2013 IdeasOnCanvas GmbH. All rights reserved.
//
#import <XCTest/XCTest.h>
@interface XCTestCase (MNAsynchronousTestCase)
- (void)mn_preformWithTimeout:(NSTimeInterval)timeout asynchronousTest:(void (^)(void))asynchronousTest;
- (void)mn_finishRunningAsynchronousTest;
@end
//
// XCTestCase+MNAsynchronousTestCase.m
// MindNodeTouch
//
// Created by Markus Müller-Simhofer on 28.07.13.
// Copyright (c) 2013 IdeasOnCanvas GmbH. All rights reserved.
//
#import "XCTestCase+MNAsynchronousTestCase.h"
#import <objc/runtime.h>
static char mn_waitingForAsynchronousTestKey;
@implementation XCTestCase (MNAsynchronousTestCase)
- (void)mn_preformWithTimeout:(NSTimeInterval)timeout asynchronousTest:(void (^)(void))asynchronousTest
{
// run test block
[self mn_setWaitingForAsynchronousTest:YES];
asynchronousTest();
NSTimeInterval timeoutTime = [[NSDate dateWithTimeIntervalSinceNow:timeout] timeIntervalSinceReferenceDate];
while ([self mn_waitingForAsynchronousTest]) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1f]];
if ([NSDate timeIntervalSinceReferenceDate] > timeoutTime) {
XCTFail(@"Test timed out! Did you forget to call -mn_finishRunningAsynchronousTest");
[self mn_setWaitingForAsynchronousTest:NO];
}
}
}
- (void)mn_finishRunningAsynchronousTest
{
[self mn_setWaitingForAsynchronousTest:NO];
}
- (void)mn_setWaitingForAsynchronousTest:(BOOL)isWaiting;
{
objc_setAssociatedObject(self, &mn_waitingForAsynchronousTestKey, @(isWaiting), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)mn_waitingForAsynchronousTest
{
NSNumber *valueObject = objc_getAssociatedObject(self, &mn_waitingForAsynchronousTestKey);
return [valueObject boolValue];
}
@end
@n-b
Copy link

n-b commented Jul 31, 2013

I used to do it without blocks on OCUnit. As far as I understand XCTesting works just the same.
https://gist.github.com/n-b/2299695

I find that using a stop flag makes it a lot simpler, but there is still room for improvement.
For example, the async test block could return a BOOL indicating if the test is completed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment