views:

36

answers:

2

I have something like

- (void)getData:(SomeParameter*)param
{
   // Remotely call out for data returned asynchronously
   // returns data via a delegate method
}


- (void)handleDataDelegateMethod:(NSData*)data
{
   // Handle returned data
}

I want to write a unit test for this, how can I do something better than

NSData* returnedData = nil;

- (void)handleDataDelegateMethod:(NSData*)data
{
   returnedData = data;
}

- (void)test
{
   [obj getData:param];
   while (!returnedData)
   {
      [NSThread sleep:1];
   }
   // Make tests on returnedData
}
+1  A: 
  1. Have your object call out to a mock from the getData: method and check that it calls out correctly.

  2. Call the handleDelegateMethod: method from another test with some ready-baked data and make sure it does whatever it's supposed to do with the data given.

Chuck
Chuck is right on--it doesn't matter that the call is asynchronous--that's the behavior of some other dependency. What's important for you to test is that the call to getData: calls its dependency, and that handleDelegateMethod: handles all the various conditions you can predict.
chrispix
A: 

If can't send mock data back to your delegate as Chuck says you could do the following:

  1. Make your test a delegate so that it receives the callback.

  2. Add fields to your test class callBackInvoked and errorHasOccurred. Set them both to NO.

  3. Make the call to getData

  4. Go around the main runloop, as follows:

     NSDate *twoSecondsFromNow = [NSDate dateWithTimeIntervalSinceNow:2.0];
     while (!callBackInvoked && !errorHasOccured && runCount-- &&  [[NSRunLoop currentRunLoop]  runMode:NSDefaultRunLoopMode beforeDate:twoSecondsFromNow]) {
       twoSecondsFromNow = [NSDate dateWithTimeIntervalSinceNow:2.0];
      }
    

    (You can set runCount to the number of times you think it would be reasonable to wait).

  5. In your handleDataDelegateMethod in the test class set callBackInvoked to YES. Similarly, if you have an error callback you can set errorHasOccured to YES.

  6. Your test should then assert that callBackInvoked is YES and erroHasOccurred is NO.

lyonanderson