Alex Rivera | Logout

OCUnit testing NSNotification delivery

Asked 2009-06-09T14:17:45.143
12

For a game I'm developing, I have several model classes that trigger notifications when their state changes. Then, the view subscribes to those notifications and can react on them.

I'm doing my unit tests for the model with OCUnit, and want to assert that the expected notifications were posted. For that, I'm doing something like this:

- (void)testSomething {
    [[NSNotificationCenter defaultCenter] addObserver:notifications selector:@selector(addObject:) name:kNotificationMoved object:board];

    Board *board = [[Board alloc] init];
    Tile *tile = [Tile newTile];

    [board addTile:tile];

    [board move:tile];

    STAssertEquals((NSUInteger)1, [notifications count], nil);
    // Assert the contents of the userInfo as well here

    [board release];
}

The idea is that the NSNotificationCenter will add the notifications to the NSMutableArray by calling its addObject: method.

When I run it, however, I see that addObject: is being sent to some other object (not my NSMutableArray) causing OCUnit to stop working. However, if I comment out some code (such as the release calls, or add a new unit test) everything starts working as expected.

I'm assuming this has to o with a timing issue, or NSNotificationCenter relying on the run loop in some way.

Is there any recommendation to test this? I know I could add a setter in Board and inject my own NSNotificationCenter, but I'm looking for a quicker way to do it (maybe some trick on how to replace the NSNotificationCenter dynamically).

Edit
Report

1 Answer

0

There are no timing issues or runloop related problems since everything in your code is non-concurrent and should be executed immediately. NSNotificationCenter only postpones notification delivery if you use an NSNotificationQueue.

I think everything is correct in the snippet you posted. Maybe there's an issue with the mutable array 'notifications'. Did you init and retain it correctly? Try to add some object manually instead of using the notification trick.

answered 2009-06-09T15:06:54.170

Your Answer