【发布时间】:2018-02-01 09:18:54
【问题描述】:
我有一个 WebSocket 服务器,我正在尝试正确测试它的一些功能。我有以下情况:
我正在接受 WebSocket 连接并在新连接上调用通道 registerConn <- 以通知 type hub struct。这是枢纽:
type hub struct {
clients map[client]bool
registerConn chan client
// some other fields below...
}
// This function runs in its own thread forever
func (h *hub) run() {
for {
select{
// A client connects on this channel
case client := <- h.registerConn:
h.clients[client] = true
}
}
}
现在,我想在hub_test.go中测试这个功能:
func TestRegisterClientWSConnections(t *testing.T){
for _, cl := range testClients {
thub.registerConn <- cl
}
// TODO: Is this a good way to test?
time.Sleep(1 * time.Second)
// I want to know if the testClients have been added to my clients map
for _, cl := range testClients {
if thub.clients[cl] == false {
t.Error("Client ", cl, " not found in the registered clients")
}
}
}
由于集线器上的 run() 函数在后台线程中运行,因此在主线程中进行检查(第二个 for 循环)之前,后台线程中的客户端注册(第一个 for 循环)尚未完成,并且由于这个原因它失败了。
解决方法是添加time.Sleep() 等待注册完成。其他解决方法是添加一个通道来通知测试添加完成。
我不想只为测试添加新频道,因为这会导致不必要的代码。另一方面,在测试中使用time.Sleep() 似乎不是一个好习惯。 (或者是吗?)
我可以通过什么方式测试这个案例?
【问题讨论】:
-
您可以将
h.clients包装成一个更可测试(和可替换)的类型,它使用一种方法来设置项目。 -
同样在这种情况下,睡一秒钟可能真的很过分。
time.Sleep(1)(一纳秒)通常就足够了。
标签: go