未观察到 OCMock 预期的通知
OCMock expected notifications were not observed
我目前正在我的代码中测试一个 class 来触发通知。放置断点,我可以看到通知已被触发,但我遇到了崩溃消息 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 还很陌生)
谢谢
这很可能是竞争条件。即使这最初通过了,测试中的竞争条件也会使它们变得脆弱,这意味着当它们偶尔失败时它们会在路上惹恼你并导致你不得不 re-run 它们全部。
完成块不保证运行运行与创建它们的线程在同一线程上。因此,它们有可能在不同的线程上被调用,这会立即导致竞争条件。
因此,您需要删除竞争条件。将原来的 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];
我目前正在我的代码中测试一个 class 来触发通知。放置断点,我可以看到通知已被触发,但我遇到了崩溃消息 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 还很陌生)
谢谢
这很可能是竞争条件。即使这最初通过了,测试中的竞争条件也会使它们变得脆弱,这意味着当它们偶尔失败时它们会在路上惹恼你并导致你不得不 re-run 它们全部。
完成块不保证运行运行与创建它们的线程在同一线程上。因此,它们有可能在不同的线程上被调用,这会立即导致竞争条件。
因此,您需要删除竞争条件。将原来的 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];