我目前正在我的代码中测试一个触发通知的类。放入断点,我可以看到通知被解雇但我收到了消息caught "OCMockTestFailure", "OCMockObserver : 3 expected notifications were not observed."
代码非常简单:
// partial mock my object
id partialMock = OCMPartialMock(myObject);
// do some basic method stubbing on my partial mock
// setup an observer
id observerMock = OCMObserverMock();
// register the mock observer to listen for notifications
[[NSNotificationCenter defaultCenter] addMockObserver:observerMock name:@"Notification1" object:[OCMArg any]];
[[NSNotificationCenter defaultCenter] addMockObserver:observerMock name:@"Notification2" object:[OCMArg any]];
[[NSNotificationCenter defaultCenter] addMockObserver:observerMock name:@"Notification3" object:[OCMArg any]];
// set the expectations
[[observerMock expect] notificationWithName:@"Notification1" object:[OCMArg any] userInfo:[OCMArg any]];
[[observerMock expect] notificationWithName:@"Notification2" object:[OCMArg any] userInfo:[OCMArg any]];
[[observerMock expect] notificationWithName:@"Notification3" object:[OCMArg any] userInfo:[OCMArg any]];
// Call the method that fires the notifications
[myObject doSomethingCoolWithCompletionBlock:^ {
OCMVerifyAll(observerMock); // <---- THROWS EXCEPTION HERE
[[NSNotificationCenter defaultCenter] removeObserver:observerMock];
}];
....
// Inside MyObject.m
// In the doSomethingCoolWithCompletionBlock
...
if (someCondition)
{
[[NSNotificationCenter defaultCenter] postNotificationName:@"Notification1" object:self];
}
else if (someOtherCondition)
{
[[NSNotificationCenter defaultCenter] postNotificationName:@"Notification2" object:self];
}
else
{
[[NSNotificationCenter defaultCenter] postNotificationName:@"Notifictaion2" object:self userInfo:@{@"ValueKey" : objectToAddToNotification}];
}
...
测试在行OCMVerifyAll(observerMock)
上抛出并发出异常,消息为error: -[MyObjectTests doSomethingCoolTest] : failed: caught "OCMockTestFailure", "OCMockObserver : 3 expected notifications were not observed."
任何拥有更多OCMock经验的人都能看到我在这里做错了什么吗? (我对OCMock来说还不够新鲜)
由于
答案 0 :(得分:2)
这很可能是一场竞争。即使这最初通过,测试中的竞争条件也会使它们变得脆弱,这意味着当它们偶尔失败并且导致你必须重新运行它们时,它们会让你烦恼。
不保证完成块在与您创建它们的线程相同的线程上运行。因此,它们可能在不同的线程上被调用,这会立即允许竞争条件。
所以,你需要删除竞争条件。将原始doSomethingCoolWithCompletionBlock
代码替换为:
[myObject doSomethingCoolWithCompletionBlock:nil];
OCMVerifyAll(observerMock);
[[NSNotificationCenter defaultCenter] removeObserver:observerMock];
编辑:根据您的评论,您还可以使用其他策略。
您可以模拟defaultCenter
并期待在那里进行通话,而不是添加您期望发布通知的观察者:
OCMockObject *mockNotificationCenter = [OCMockObject partialMockForObject:[NSNotificationCenter defaultCenter]];
[[mockNotificationCenter expect] postNotificationName:@"Notification1" object:OCMOCK_ANY];
// etc..
// doSomethingCool code goes here
[mockNotificationCenter verify];