在 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 框架会为您发布通知?无论如何,这是我在您的方法中看到的问题:
您需要 运行 在监视 postNotification 选择器之后和断言监视参数的值之前发布通知的操作。从您发布的代码来看,目前尚不清楚是否正在发生这种情况。
如果确实调用了 postNotification 方法,此解决方案应该有效。我其实不认为这是一个异步问题。我经常监视 postNotificationName:object:userInfo: 在 defaultCenter 上成功并且没有特殊的异步处理代码。
为了检查 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"]];
就我个人而言,我会选择自定义匹配器方法,它更优雅、更灵活。
所以我需要测试是否发布了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 框架会为您发布通知?无论如何,这是我在您的方法中看到的问题:
您需要 运行 在监视 postNotification 选择器之后和断言监视参数的值之前发布通知的操作。从您发布的代码来看,目前尚不清楚是否正在发生这种情况。
如果确实调用了 postNotification 方法,此解决方案应该有效。我其实不认为这是一个异步问题。我经常监视 postNotificationName:object:userInfo: 在 defaultCenter 上成功并且没有特殊的异步处理代码。
为了检查 Kiwi 中字符串的相等性,不要将它们包装在 theValue() 中。 theValue() 用于检查标量属性的相等性。你的断言应该是这样的:
[[((NSNotification*)notificationSpy.argument).name should] equal:@"myNotificationName"];
如果这不能帮助您找到解决方案,请提供您正在测试的方法的更多代码和完整的测试方法,以及任何其他有用的信息。
如果您希望在将来某个时间发送通知,您可以使用 expectFutureValue():
[[expectFutureValue(((NSNotification*)notificationSpy.argument).name) shouldEventually] equal:@"MyNotification"];
您也不会得到 NSInternalConsistencyException
异常,因为如果包裹在 expectFutureValue
.
其他选择是
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"]];
就我个人而言,我会选择自定义匹配器方法,它更优雅、更灵活。