猿问

如何告诉我的测试等待 goroutine 中的回调?

我正在使用 dockerclient https://github.com/samalba/dockerclient,它有一个基于通道的 API 来监听事件client.MonitorEvents()和一个方便的回调方法client.StartMonitorEvents(callbackHandler)。


我想测试处理程序是否被调用。当然,dockerclient 在 goroutine 中处理事件。


现在,我的处理程序只是吐出一个日志。如果我在考试中等待,一切都会得到处理。如果我不这样做,它会在处理任何事情之前退出:


func eventCallback(event *dockerclient.Event, ec chan error, args ...interface{}) {

  log.Printf("Received event: %#v\n", *event)

}

我的测试似乎很简单:


func TestReceiveEvent(t *testing.T) {

   createAndMonitorEvents(server.URL)

   <- eventReady

   eventWriter.Write([]byte(someEvent))

   // test for something here

}

当然,除非我time.Sleep()因为goroutine而放入a ,否则它不起作用。


我如何告诉我的测试,“在运行测试之前等待其他例程完成它的工作”,而不是进入一些任意睡眠?我希望测试我的处理程序是否正确处理了该事件。


备用接口client.MonitorEvents()返回一个通道,这给了我更大的控制权,但是通道的接收会吐出无限nil事件。


沧海一幻觉
浏览 159回答 3
3回答

慕的地6264312

我认为当您使用nils 时MonitorEvents,您只会看到事件通道已关闭(包括 a的来源MonitorEventsclose(eventOrErrorChan),支持这一点)。evt, ok := <-c让您直接检查它是否(ok关闭时为假),并for evt := range c在关闭后停止。通常,从关闭的通道接收被指定为“在接收到任何先前发送的值之后[产生]元素类型的零值”关于等待回调的问题:回调可以关闭一个通道。(或发送给它。)然后您的测试可以等待指定的时间长度select:select {case <-c:&nbsp; &nbsp; &nbsp; &nbsp; /* ...success... */case <-time.After(5 * time.Second):&nbsp; &nbsp; &nbsp; &nbsp; /* timed out */}如果您知道某些错误条件导致处理程序无法完成或无法运行,则它可能会在不同的通道上发出这些情况的信号,或者通过向 发送不同的值c。

弑天下

“我如何告诉我的测试,“在运行测试之前等待其他例程完成它的工作”,而不是任意睡眠?”您可以在频道上发送或关闭频道。调用者正在接收执行块,直到信号发生。我真的不明白如何将你的代码处理成有意义的东西......你不能在函数中分配停止通道,你必须将它传递给函数以便调用者可以监听它。就像这甚至如何编译?func TestReceiveEvent(t *testing.T) {&nbsp; &nbsp;createAndMonitorEvents(server.URL)&nbsp; &nbsp;<- eventReady // undeclared variable, and discarding the event you recieved?&nbsp; &nbsp;eventWriter.Write([]byte(someEvent)) //and another variable that is not declared&nbsp; &nbsp;// test for something here}也许和想法会帮助你开始......func createAndMonitorEvents(url string, done chan bool) {&nbsp; &nbsp; &nbsp; //the codes&nbsp; &nbsp; &nbsp; close(done)}func TestReceiveEvent(t *testing.T) {&nbsp; eventReady := make(chan bool)&nbsp; &nbsp; createAndMonitorEvents(server.URL, eventReady)&nbsp; &nbsp; <- eventReady&nbsp; &nbsp; eventWriter.Write([]byte(someEvent)) // dis still don't exist though&nbsp; &nbsp; // test for something here}
随时随地看视频慕课网APP

相关分类

Go
我要回答