在我的基础模拟课程中:
- (void)tearDown
{
_mockApplication = nil;
self.observerMock = nil;
self.notificationCenterMock = nil;
}
其中notificaitonCenterMock只是一个id;
然后在我的测试中我做了这样的事情:
self.notificationCenterMock = [OCMockObject partialMockForObject:[NSNotificationCenter defaultCenter]];
[(NSNotificationCenter *) [self.notificationCenterMock expect]
removeObserver:self.component
name:UIApplicationDidBecomeActiveNotification
object:nil];
现在..如果我运行这个代码,我的单元测试将虚假地失败(即一次运行中只有60个运行,下一个运行时运行70或65)。我的一些单元测试将失败并出现以下错误:
OCPartialMockObject[NSNotificationCenter]: expected method was not invoked: removeObserver:
<VPBCAdComponent-0x17d43e0-384381847.515513: 0x17d43e0> name:@"UIApplicationDidBecomeActiveNotification" object:nil
Unknown.m:0: error: -[VPBCAdComponentTests testCleanUpAfterDisplayingClickthrough_adBrowser_delegateCallback] :
OCPartialMockObject[NSNotificationCenter]: expected method was not invoked: removeObserver:
<VPBCAdComponent-0x17d43e0-384381847.515513: 0x17d43e0> name:@"UIApplicationDidBecomeActiveNotification" object:nil
然后测试将被终止。我可以清楚地看到,部分模拟通知中心会导致运行测试套件出现问题。
问题是,我该怎么办?确保观察者等重要事物的设定和回归证明是非常好的。
答案 0 :(得分:0)
如果你能在这种情况下避免局部模拟,那就去做吧。如果您只想测试添加和删除观察者,您应该能够使用标准模拟或漂亮模拟。
如果您只能隔离几个可以验证添加和删除观察者的测试,那么它应该没有这种连锁反应?
id mockCenter = [OCMockObject mockForClass:[NSNotificationCenter class]];
[[mockCenter expect] addObserver:observer options:UIApplicationDidBecomeActiveNotification context:nil];
// method on the Subject Under Test
[mockCenter verify];
答案 1 :(得分:0)
我个人在这种情况下使用当地的嘲笑。较小的模拟范围可确保较少干扰应用程序的其他部分。在NSUserDefaults或其他共享对象的情况下更重要。我使用的测试模式是相同的。
- (void)testRegisterNofificaitonTest {
id ncMock = OCMClassMock([NSNotificationCenter class]);
OCMStub([ncMock defaultCenter]).andReturn(ncMock);
UIViewController *sut = [UIViewController new];
[[ncMock expect] addObserver:sut selector:@selector(doSomething:) name:@"NotificationName" object:nil];
[sut viewDidLoad]; //assuming viewDidLoad calls [[NSNotificationCenter defaultCenter] addObserver: ...
[ncMock verify];
[ncMock stopMocking];
}