我正在使用SocketRocket库来处理连接到Websocket。它连接得很好,但我正在尝试运行一些必须首先等待WS连接的单元测试。由于知道WS已连接的唯一方法是通过其委托方法,因此我无法使此进程同步。我希望我的单元测试'setup
方法简单地创建一个WS连接,然后tearDown
关闭它。
我为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);
}
}
答案 0 :(得分:4)
当您等待信号量发出信号时,主线程被阻止,因此根本无法运行任何代码。如果您的库与runloop系统集成,您可以使用CFRunLoopRun()
运行runloop,而不是等待您的信号量。从准备好的回调中,您可以使用CFRunLoopStop( CFRunLoopGetMain() )
停止runloop。