title: Pattern for unit testing async queue that calls main queue on completion
body: <p>This is related to my previous <a href="https://stackoverflow.com/questions/7816159/dispatch-sync-on-main-queue-hangs-in-unit-test">question</a>, but different enough that I figured I'd throw it into a new one.  I have some code that runs async on a custom queue, then executes a completion block on the main thread when complete.  I'd like to write unit test around this method.  My method on <code>MyObject</code> looks like this.</p>
  
  <pre><code>+ (void)doSomethingAsyncThenRunCompletionBlockOnMainQueue:(void (^)())completionBlock {
  
      dispatch_queue_t customQueue = dispatch_queue_create("com.myObject.myCustomQueue", 0);
  
      dispatch_async(customQueue, ^(void) {
  
          dispatch_queue_t currentQueue = dispatch_get_current_queue();
          dispatch_queue_t mainQueue = dispatch_get_main_queue();
  
          if (currentQueue == mainQueue) {
              NSLog(@"already on main thread");
              completionBlock();
          } else {
              dispatch_async(mainQueue, ^(void) {
                  NSLog(@"NOT already on main thread");
                  completionBlock();
          }); 
      }
  });
  </code></pre>
  
  <p>}</p>
  
  <p>I threw in the main queue test for extra safety, but It always hits the <code>dispatch_async</code>.  My unit test looks like the following.</p>
  
  <pre><code>- (void)testDoSomething {
  
      dispatch_semaphore_t sema = dispatch_semaphore_create(0);
  
      void (^completionBlock)(void) = ^(void){        
          NSLog(@"Completion Block!");
          dispatch_semaphore_signal(sema);
      }; 
  
      [MyObject doSomethingAsyncThenRunCompletionBlockOnMainQueue:completionBlock];
  
      // Wait for async code to finish
      dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
      dispatch_release(sema);
  
      STFail(@"I know this will fail, thanks");
  }
  </code></pre>
  
  <p>I create a semaphore in order to block the test from finishing before the async code does.  This would work great if I don't require the completion block to run on the main thread.  However, as a couple folks pointed out in the question I linked to above, the fact that the test is running on the main thread and then I enqueue the completion block on the main thread means I'll just hang forever.</p>
  
  <p>Calling the main queue from an async queue is a pattern I see a lot for updating the UI and such.  Does anyone have a better pattern for testing async code that calls back to the main queue?</p>