在 Kiwi 中测试 NSNotification iOS

Testing NSNotification in Kiwi iOS

所以我需要测试是否发布了NSNotification。我尝试了以下代码来监视参数。

[[NSNotificationCenter defaultCenter] stub:@selector(postNotification:)];

__block KWCaptureSpy *notificationSpy = [[NSNotificationCenter 
defaultCenter] captureArgument:@selector(postNotification:) atIndex:0];

[[theValue(notificationSpy.argument.name) should] equal:theValue(SOME_NOTIFICATION)];

但问题是因为它是异步的,所以在测试之前并不总是捕获参数。我无法为 notificationSpy.argument.name 添加 shouldEventually,因为它抛出 NSInternalConsistencyException 用于在捕获之前访问参数。

我也试过了, [[SOME_NOTIFICATION should] bePosted]; 它也失败了。

我可能遗漏了一些上下文,因为您没有解释正在测试的代码。你在发通知吗?还是您要断言 IOS 框架会为您发布通知?无论如何,这是我在您的方法中看到的问题:

  1. 您需要 运行 在监视 postNotification 选择器之后和断言监视参数的值之前发布通知的操作。从您发布的代码来看,目前尚不清楚是否正在发生这种情况。

  2. 如果确实调用了 postNotification 方法,此解决方案应该有效。我其实不认为这是一个异步问题。我经常监视 postNotificationName:object:userInfo: 在 defaultCenter 上成功并且没有特殊的异步处理代码。

  3. 为了检查 Kiwi 中字符串的相等性,不要将它们包装在 theValue() 中。 theValue() 用于检查标量属性的相等性。你的断言应该是这样的:

    [[((NSNotification*)notificationSpy.argument).name should] equal:@"myNotificationName"];
    

如果这不能帮助您找到解决方案,请提供您正在测试的方法的更多代码和完整的测试方法,以及任何其他有用的信息。

如果您希望在将来某个时间发送通知,您可以使用 expectFutureValue()

[[expectFutureValue(((NSNotification*)notificationSpy.argument).name) shouldEventually] equal:@"MyNotification"];

您也不会得到 NSInternalConsistencyException 异常,因为如果包裹在 expectFutureValue.

中,Kiwi 似乎可以很好地处理尚未解决的间谍问题

其他选择是

  • stub sendNotification: 方法和 "manually" 捕获发送的通知:

    __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"];
    
  • 编写一个注册到通知中心的自定义匹配器并在该匹配器上断言:

    [[[NSNotificationCenter defaultCenter] shouldEventually] sendNotification:@"MyNotification"]];
    

就我个人而言,我会选择自定义匹配器方法,它更优雅、更灵活。