OCMock在线程环境中混淆引用

时间:2013-03-27 19:46:12

标签: objective-c ocmock

我有一段代码,它同步和异步地处理队列。我正在使用OCMock来测试这个东西而且我可以单独测试这两种情况(同步和异步)但是当我同时测试两种情况时我都会遇到麻烦。

要验证队列是否正确处理,我将它传递给一个模拟的侦听器,然后从这个侦听器中我询问它是否得到了队列处理器传播的所有通知。我有两个测试,在第一个测试(异步)中满足这些期望但是第二个测试(同步)我得到了这个错误:

OCMockObject[JHQueueListener] : 4 expected methods were not invoked: 
        startedProcessingQueue
        startedToProcessQueueItem:OCMockObject[JHQueueItem]
        finishedProcessingQueueItem:OCMockObject[JHQueueItem]
        finishedProcessingQueue

这是项目的链接: https://github.com/jphollanti/queue-processor

这是测试的链接: https://github.com/jphollanti/queue-processor/blob/master/QueueProcessorTests/JHQueueProcessorTests.m

1 个答案:

答案 0 :(得分:0)

问题#1: 引用很好,但是当涉及到测试时,线程预计会无法正常工作。这里的问题是启动一个新线程,并在该新线程中将队列的状态设置为正在进行中。但是启动新线程所花费的时间比主线程要求状态所需的时间长,这导致队列尚未(尚未)进行。添加大约10000毫秒的延迟应该会有很多帮助。像这样:

...
  [queue processQueueAsynchronously:queueItems];

  usleep(10000);

  BOOL wentToThread = NO;
  while ([queue isInProgress]) {
    wentToThread = YES;
    ...
  }
...

此外,调用dispatch_async(dispatch_queue_t queue, ^(void)block)需要花费大量时间,这也会增加问题的“随机”性质。

问题#2: 从主线程调用dispatch_async(dispatch_get_main_queue(), ^{ ... }会导致将块发送到某个队列,该队列会在某个时间执行(不要知道它是如何工作的)。这就是第二次测试(同步)失败的原因。使用这样的东西有助于:

if ([NSThread isMainThread]) {
  for (id <JHQueueListener> listener in listeners) {
    [listener startedToProcessQueueItem:queueItem];
  }
} else {
  dispatch_async(dispatch_get_main_queue(), ^{
    for (id <JHQueueListener> listener in listeners) {
      [listener startedToProcessQueueItem:queueItem];
    }
  });
}