为什么OCMock在使用mockObserver时会导致nsnotificaiton中心拥有EXC_BAD_ACCESS

时间:2013-02-25 16:47:42

标签: ocmock

我设置了这样的模拟观察者:

id quartileObserverMock = [OCMockObject observerMock];
[[NSNotificationCenter defaultCenter] addMockObserver:quartileObserverMock
                                                 name:kVPAdPlayerDidReachQuartileNotification
                                               object:self.adPlayer];

[[quartileObserverMock expect]
                       notificationWithName:kVPAdPlayerDidReachQuartileNotification
                                     object:self.adPlayer
                                   userInfo:@{@"quartile" : @(VPAdPlayerFirstQuartile), @"trackingEvent" : VPCreativeTrackingEventFirstQuartile}];

我的单元测试运行;但是当发布通知时,我得到了虚假的EXC_BAD_ACCESS错误。

[[NSNotificationCenter defaultCenter]
                           postNotificationName:kVPAdPlayerDidReachQuartileNotification
                                         object:self.adPlayer
                                       userInfo:@{@"quartile" : @(quartile), @"trackingEvent" : trackingEvent}];

当我注释掉observermock代码时,我的测试每次都运行良好。

当我重新输入代码时,我在postNotiicaitonName:object:userInfo上发生虚假崩溃,可能每2.5次一次。

有人有任何想法吗?

2 个答案:

答案 0 :(得分:8)

请参阅以下示例代码,这可能对您有所帮助。它对我有用

- (void)test__postNotificationwithName__withUserInfo
{
     id observerMock  = [OCMockObject observerMock];
     [[NSNotificationCenter defaultCenter] addMockObserver:observerMock name:@"NewNotification" object:nil];

     NSDictionary *userInfo = [[NSDictionary alloc] initWithObjectsAndKeys:@"2",@"2", nil];
     [[observerMock expect] notificationWithName:@"NewNotification" object:[OCMArg any] userInfo:userInfo];

     NotificationClass *sut = [[NotificationClass alloc] init];
     [sut postNotificationwithName:@"NewNotification" userInfo:userInfo];

     [[NSNotificationCenter defaultCenter] removeObserver:observerMock];
     [observerMock verify];
}

和我的发布通知方法

- (void)postNotificationwithName:(NSString *)notifName userInfo:(NSDictionary *)userInfo
{
     [[NSNotificationCenter defaultCenter] postNotificationName:notifName object:self userInfo:userInfo];
}

请注意:

  1. 在收到意外通知时,observerMock总是引发异常。
  2. 在测试用例结束时从NSNotificationCenter中删除模拟的观察者。

答案 1 :(得分:1)

有几个原因导致这种情况发生(我知道,因为我今天在我自己的代码中解决了这两个问题)

1)未删除先前测试的模拟观察者

2)来自先前测试的非模拟实例对象正在观察相同的通知,但该对象已经过时。在我的例子中,我的setUp方法中的实例对象正在监听通知,但是当它被解除分配时,它并没有从NSNotificationCenter的观察者列表中删除它。

在这两种情况下,解决方案都是使用

  [[NSNotificationCenter defaultCenter] removeObserver:name:object:]

取决于范围:1)在观察NSNotificationCenter的所有类的dealloc中,2)在tearDown方法中,或3)在测试用例结束时(如@PrasadDevadiga所述) )