如何使用OCMock测试NSNotificationCenter中的addObserver和removeObserver是否被调用

3

在我的基础模拟类中:

- (void)tearDown
{
    _mockApplication = nil;
    self.observerMock = nil;
    self.notificationCenterMock = nil;
}

其中notificaitonCenterMock只是一个标识符;

然后在我的测试中,我会这样做:

self.notificationCenterMock = [OCMockObject partialMockForObject:[NSNotificationCenter defaultCenter]];
[(NSNotificationCenter *) [self.notificationCenterMock expect]
        removeObserver:self.component
                  name:UIApplicationDidBecomeActiveNotification
                object:nil];

现在,如果我运行这段代码,我的单元测试将会出现错误(即一次只有60个测试用例中的370个会被运行,下一次则是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

测试将会被终止。我清楚地看到,部分模拟通知中心会导致运行测试套件时出现问题。

问题是,我该怎么办?确保设置了重要的观察者和回归证明将非常好。


更具体地说,我如何在拆卸中删除模拟?似乎将其设置为nil是不够的。 - Infrid
你在哪里调用了removeObserver? - psobko
2个回答

0

如果在这种情况下可以避免使用部分模拟,请这样做。如果您只想测试观察者是否已添加和删除,则应该能够使用标准模拟或好模拟。

如果您可以仅隔离一些测试来验证观察者是否已添加和删除,那么它就不应该产生如此大的影响,对吗?

id mockCenter = [OCMockObject mockForClass:[NSNotificationCenter class]];
[[mockCenter expect] addObserver:observer options:UIApplicationDidBecomeActiveNotification context:nil];

// method on the Subject Under Test

[mockCenter verify];

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];
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接