簡體   English   中英

如何告訴我的測試等待goroutine中的回調?

[英]How do I tell my test to wait for a callback in a 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
}

當然,除非有goroutine,否則除非我輸入time.Sleep() ,否則它不會起作用。

我如何告訴我的測試,“除了等待一些睡眠以外,”在運行測試之前先等待其他例程完成工作? 我正在測試我的處理程序是否正確處理了該事件。

備用接口client.MonitorEvents()返回一個通道,它為我提供了更大的控制權,但是從該通道接收信號會發出無限個nil事件。

更新:

根據要求,createAndMonitorEvents為:

func createAndMonitorEvents(url string) {
  // Init the client
  docker, _ := dockerclient.NewDockerClient(url, nil)

  // Listen to events
  stopchan := make(chan struct{})

  go func() {
    eventErrChan, err := docker.MonitorEvents(nil, stopchan)
    if err != nil {
        return
    }

    for e := range eventErrChan {
        if e.Error != nil {
            return
        }
        eventCallback(&e.Event, nil)
    }
    fmt.Println("monitor in place")
  }()
}

MonitorEvents您使用MonitorEvents獲得nil時,您只是看到事件通道已關閉( MonitorEvents包含close(eventOrErrorChan) ,支持此操作)。 evt, ok := <-c可讓您直接檢查是否這樣做(關閉時ok將為假), for evt := range c將在關閉后停止。 通常,將從封閉通道接收的數據指定為“ [已接收到任何先前發送的值后,元素類型的零值[屈服]”

關於等待回調的問題:回調可以關閉通道。 (或發送給它。)然后,您可以使用select等待指定的時間長度:

select {
case <-c:
        /* ...success... */
case <-time.After(5 * time.Second):
        /* timed out */
}

如果您知道某些錯誤情況導致處理程序無法完成或無法運行,則可能會在其他通道上發信號通知這些情況,或者向c發送不同的值。

我認為這可以幫助

WaitGroup等待goroutine的集合完成。 主goroutine調用添加以設置要等待的goroutine的數量。 然后,每個goroutine都會運行並在完成后調用Done。 同時,可以使用Wait來阻塞,直到所有goroutine完成。

http://golang.org/pkg/sync/#example_WaitGroup

“除了讓我任意睡覺之外,我如何告訴我的測試“在運行測試之前先等待其他例程完成工作”?

您可以發送一個頻道,也可以關閉一個頻道。 調用方正在接收執行塊的位置,直到出現信號為止。 我真的看不到如何將代碼工作成有意義的東西……您無法在函數中分配停止通道,必須將其傳遞給函數,以便調用者可以監聽它。 像這樣怎么編譯?

func TestReceiveEvent(t *testing.T) {
   createAndMonitorEvents(server.URL)
   <- eventReady // undeclared variable, and discarding the event you recieved?
   eventWriter.Write([]byte(someEvent)) //and another variable that is not declared
   // test for something here
}

也許可以幫助您入門的想法...

func createAndMonitorEvents(url string, done chan bool) {
      //the codes
      close(done)
}


func TestReceiveEvent(t *testing.T) {
  eventReady := make(chan bool)
    createAndMonitorEvents(server.URL, eventReady)
    <- eventReady
    eventWriter.Write([]byte(someEvent)) // dis still don't exist though
    // test for something here

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM