Reputation: 1522
So I need to test whether a NSNotification
is posted. I tried the following code to spy on the argument.
[[NSNotificationCenter defaultCenter] stub:@selector(postNotification:)];
__block KWCaptureSpy *notificationSpy = [[NSNotificationCenter
defaultCenter] captureArgument:@selector(postNotification:) atIndex:0];
[[theValue(notificationSpy.argument.name) should] equal:theValue(SOME_NOTIFICATION)];
but the problem with this is the since it's asynchronous the argument is not always captured before testing. I can't add shouldEventually
for notificationSpy.argument.name either as it throws NSInternalConsistencyException
for accessing the argument before capturing.
I also tried,
[[SOME_NOTIFICATION should] bePosted];
and it failed as well.
Upvotes: 1
Views: 488
Reputation: 32919
You can use expectFutureValue() if you expect the notification to be sent sometime in the future:
[[expectFutureValue(((NSNotification*)notificationSpy.argument).name) shouldEventually] equal:@"MyNotification"];
You also won't get the NSInternalConsistencyException
exception, as Kiwi seems to work fine with spies not yet resolved, if wrapped inside a expectFutureValue
.
Other alternatives would be to
stub
the sendNotification:
method and "manually" capture the sent notification:
__block NSString *notifName = nil;
[[NSNotificationCenter defaultCenter] stub:@selector(postNotification:) withBlock:^id(NSArray *params) {
NSNotification *notification = params[0];
notifName = notification.name;
return nil;
}];
[[notifName shouldEventually] equal:@"TestNotification"];
write a custom matcher that registers to the notification center and assert on that matcher:
[[[NSNotificationCenter defaultCenter] shouldEventually] sendNotification:@"MyNotification"]];
Personally, I'd go with the custom matcher approach, it's more elegant and more flexible.
Upvotes: 3
Reputation: 366
I may be missing some context because you haven't explained the code being tested. Are you posting a notification? Or are you trying to assert that the IOS Framework posts a notification for you? Regardless, here are the problems I see with your approach:
You need to run the action that posts the notification AFTER spying on the postNotification selector and BEFORE you assert the value of the spied argument. From the code you posted, It is not clear that this is happening.
This solution SHOULD work if indeed the postNotification method is being called. I actually do not think this is an asynchronous problem. I frequently spy on the postNotificationName:object:userInfo: on the defaultCenter with success and no special async handling code.
For checking equality of strings in Kiwi, do not wrap them in theValue(). theValue() is used to check equality on scalar properties. your assertion should look like this:
[[((NSNotification*)notificationSpy.argument).name should] equal:@"myNotificationName"];
If this doesn't help get you your solution, please provide more code of the methods you are testing and the test methods in their entirety, as well as any other useful information.
Upvotes: 2