2013-03-27 5 views
0

동기식 및 비동기식으로 큐를 처리하는 코드가 있습니다. OCMock을 사용하여 테스트하고 개별적으로 (동기식 및 비동기식) 모두 테스트 할 수 있지만 동시에 테스트 할 때 문제가 발생합니다.OCMock이 스레드 환경에서 참조를 혼동합니다.

대기열이 올바르게 처리되었는지 확인하려면 조롱받은 수신기를 전달하고이 수신기에서 대기열 처리기에 의해 전파되는 모든 알림이 있는지 묻는 것입니다. 나는 두 가지 검사를하고, 첫 번째 테스트 (비동기)에서 이러한 기대는 충족하지만 두 번째 테스트 (동기)와 함께이 오류 얻을 : https://github.com/jphollanti/queue-processor

그리고 다음은

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

프로젝트에 대한 링크의를 https://github.com/jphollanti/queue-processor/blob/master/QueueProcessorTests/JHQueueProcessorTests.m

+0

실행 여부를 확인하기 전에 큐 프로세서가 실행되기 시작 했습니까? 이 경우 아직 처리하지 않았기 때문에 inProcess 검사에서 빠져 나올 수 있습니다. 그리고 OCMock은 작업을 끝내기 전에 아무 일도 일어나지 않았다고 정확하게 말할 것입니다. – gaige

+0

제안 해 주셔서 감사합니다. 그건 사실이 아니었지만 나는 그 문제에 앞서 나아갈 수 있었다. 그것은 (NSThread isMainThread)를 확인하고 알림이 이미 메인 스레드에 있다면 조금씩 다르게 보냈다. 하지만 여전히 이상한 점은 이제 어떻게 든 무작위로 실패하고 있다는 것입니다. 이상한. – JHollanti

답변

0

이슈 # 1 : 참조가 미세하지만이 테스트에 올 때, 나사가에서 작동 할 것으로 예상된다 여기 테스트에 대한 링크입니다 바르게. 여기서 문제는 새 스레드가 시작되고 새 스레드에서 큐의 상태가 진행중인 것으로 설정된다는 것입니다. 그러나 주 스레드가 상태를 요청하는 것보다 새로운 스레드를 시작하는 데 시간이 오래 걸리므로 대기열이 (아직) 진행 중이 아님을 나타냅니다. 약 10000ms의 지연을 추가하면 많은 도움이됩니다. 그래서 같이 : dispatch_async(dispatch_queue_t queue, ^(void)block)를 호출 또한

... 
    [queue processQueueAsynchronously:queueItems]; 

    usleep(10000); 

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

, 많은 시간을 소요하고이 문제의 "랜덤"성격까지 추가합니다.

문제 # 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]; 
    } 
    }); 
}