2013-02-17 313 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