views:

229

answers:

2

What's the best way to sleep/wait until certain notification is posted?

I've got class with asynchronous API that gets data from NSNotification (notification comes from Cocoa, I can't avoid it) and I need to unit test it.

So far I've figured out semi-busy wait:

[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:10]]

without processing of run loop notifications aren't received. But how can I break from run loop immediately when desired notification comes?

+1  A: 

If this is just about unit testing your code's reaction to a notification, I think that causing the thread to sleep may be overkill. A few questions come to mind...

  1. How you will test whether the notification response is a pass or fail — are there any measurable side effects you can test?
  2. Can you send your own NSNotification an measure the response? (You mention that NSRunLoop usually handles it, but if you can mock the notification, testing will be more predictable.)
  3. If (for some reason) you're trying to test whether the notification is sent at all, is there a need? (If it's automatic, don't bother — if it's user-generated, unit testing it can be hard, but mocking it can simplify things.)

If you really need to create a multi-threaded scenario to test, you might look at testLockUnlock in this unit test code for an example. (I was just trying to make sure that my code was properly using locks built into a collection or generalized mutable object.)

Quinn Taylor
+2  A: 

runMode:beforeDate: will run the loop just once, so you can use that call in a loop until you detect that the notification has been handled (if nothing else, your handler can flip a member variable in your test class to YES).

smorgan