2013-02-17 322 views
5

我正在使用SocketRocket庫來處理連接到WebSocket。它連接好,但我試圖運行一些單位測試,必須先等待WS連接。因爲知道WS已經連接的唯一方法是通過它的委託方法,所以我很難使這個過程同步。我想單元測試'setup方法來簡單地創建一個WS連接,然後tearDown關閉它。暫停執行,直到Websocket連接

我爲我的Websocket類實現了兩種類型的連接方法。前兩個是非常基本的,我已經驗證他們按預期工作。最後一個是我試圖阻止它主要用於測試目的。我一直無法實現它的工作,並且最終只能等到永遠,所以我認爲這是我的概念誤解。

我想我的一個大問題是,如何在測試用例中停止執行以等待對代理的返回調用?測試用例中出現的問題是,我不能只在完成塊中完成所有的測試 - 測試方法將此視爲成功並結束程序。

- (void)connect 
{ 
    DLog(@"Websocket is connecting now"); 
    [_socket open]; 
} 


- (void)connectWithCompletion:(WebsocketConnection)completion 
{ 
    DLog(@"Connecting now..."); 
    [_onConnectBlocksToRun addObject:^{ 
     completion(self.isConnected, self.socket); 
    }]; 
    [_socket open]; 
} 

- (bool)connectBlocking // XXX Doesn't work! 
{ 
    sem = dispatch_semaphore_create(0); 
    [_socket open]; 

    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); 
    return _isConnected; 
} 

#pragma mark - Socket rocket delegate 
- (void)webSocketDidOpen:(SRWebSocket *)webSocket 
{ 
    DLog(@"Websocket has opened"); 
    _isConnected = YES; 
    _socket = webSocket; 

    for (void(^block)() in _onConnectBlocksToRun) { 
     block(); 
    } 
    [_onConnectBlocksToRun removeAllObjects]; 

    if (sem) { 
     dispatch_semaphore_signal(sem); 
     dispatch_release(sem); 
    } 
} 

回答

4

當你正在等待得到信號的信號主要線程被阻塞,所以沒有代碼可以運行在所有。如果您的庫與runloop系統集成,則可以使用CFRunLoopRun()運行runloop,而不是等待您的信號量。從你準備好的回調中,你可以使用CFRunLoopStop(CFRunLoopGetMain())來停止runloop。

+0

是的!這工作完美,我學到了新東西。謝謝! – joslinm 2013-02-17 17:53:49