2013-03-27 37 views
0

我有一段代碼,它正在同步和異步地處理一個隊列。我正在使用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

+0

確定隊列處理器是否開始執行,然後再檢查它是否正在執行?在這種情況下,您會因爲您尚未處理而退出inProcess檢查,然後OCMock會在您完成之前正確地告訴您沒有任何事情發生。 – gaige 2013-03-27 20:44:22

+0

感謝您的建議。事實並非如此,但我設法解決了這個問題。事實證明,我必須檢查([NSThread isMainThread]),然後發送通知有點不同,如果它已經在主線程中。但是奇怪的是,它現在不知何故隨機失敗......奇怪。 – JHollanti 2013-03-27 21:05:14

回答

0

問題#1:的參考文獻都是精品,但是當涉及到測試,螺紋有望在工作正確。這裏的問題是一個新的線程被啓動,並且在新的線程中隊列的狀態被設置爲正在進行中。但是,啓動一個新線程需要比主線程要求狀態更長的時間,並且這導致隊列尚未(尚未)進行。增加大約10000ms的延遲應該會有很大的幫助。像這樣:

... 
    [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]; 
    } 
    }); 
}