title: XCTestExpectation: how to avoid calling the fulfill method after the wait context has ended?
body: <p>I’m using the new asynchronous testing capabilities of Xcode 6. Everything works fine when the asynchronous task ends before the timeout. But if the task takes longer than the timeout, things get more complicated.</p>
  
  <p>Here is how I’m doing my tests:</p>
  
  <pre class="lang-c prettyprint-override"><code>@interface AsyncTestCase : XCTestCase @end
  
  @implementation AsyncTestCase
  
  // The asynchronous task would obviously be more complex in a real world scenario.
  - (void) startAsynchronousTaskWithDuration:(NSTimeInterval)duration completionHandler:(void (^)(id result, NSError *error))completionHandler
  {
      dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
          completionHandler([NSObject new], nil);
      });
  }
  
  - (void) test1TaskLongerThanTimeout
  {
      XCTestExpectation *expectation = [self expectationWithDescription:@"Test 1: task longer than timeout"];
      [self startAsynchronousTaskWithDuration:4 completionHandler:^(id result, NSError *error) {
          XCTAssertNotNil(result);
          XCTAssertNil(error);
          [expectation fulfill];
      }];
      [self waitForExpectationsWithTimeout:2 handler:nil];
  }
  
  - (void) test2TaskShorterThanTimeout
  {
      XCTestExpectation *expectation = [self expectationWithDescription:@"Test 2: task shorter than timeout"];
      [self startAsynchronousTaskWithDuration:5 completionHandler:^(id result, NSError *error) {
          XCTAssertNotNil(result);
          XCTAssertNil(error);
          [expectation fulfill];
      }];
      [self waitForExpectationsWithTimeout:10 handler:nil];
  }
  
  @end
  </code></pre>
  
  <p>Unfortunately, calling the <code>fulfill</code> method after the timeout has expired crashes the test suite with this error:</p>
  
  <blockquote>
    <p>API violation - called -[XCTestExpectation fulfill] after the wait context has ended.</p>
  </blockquote>
  
  <pre><code>*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'API violation - called -[XCTestExpectation fulfill] after the wait context has ended.'
  *** First throw call stack:
  (
    0   CoreFoundation   0x000000010c3a6f35 __exceptionPreprocess + 165
    1   libobjc.A.dylib  0x000000010a760bb7 objc_exception_throw + 45
    2   CoreFoundation   0x000000010c3a6d9a +[NSException raise:format:arguments:] + 106
    3   Foundation       0x000000010a37d5df -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195
    4   XCTest           0x0000000115c48ee1 -[XCTestExpectation fulfill] + 264
    ...
  )
  libc++abi.dylib: terminating with uncaught exception of type NSException
  </code></pre>
  
  <p>Of course I can check if the test is finished before calling the <code>fulfill</code> method like this:</p>
  
  <pre class="lang-c prettyprint-override"><code>- (void) test1TaskLongerThanTimeout
  {
      XCTestExpectation *expectation = [self expectationWithDescription:@"Test 1: task longer than timeout"];
  
      __block BOOL testIsFinished = NO;
      [self startAsynchronousTaskWithDuration:4 completionHandler:^(id result, NSError *error) {
          if (testIsFinished) {
              return;
          }
          XCTAssertNotNil(result);
          XCTAssertNil(error);
          [expectation fulfill];
      }];
  
      [self waitForExpectationsWithTimeout:2 handler:^(NSError *error) {
          testIsFinished = YES;
      }];
  }
  </code></pre>
  
  <p>But this seems overly complicated and makes the test much harder to read. Am I missing something? Is there a simpler way to solve this problem?</p>