title: How do I tell my test to wait for a callback in a goroutine?
body: <p>I am using the dockerclient <a href="https://github.com/samalba/dockerclient" rel="nofollow">https://github.com/samalba/dockerclient</a> which has a channel-based API to listen for events <code>client.MonitorEvents()</code> and a convenient callback method <code>client.StartMonitorEvents(callbackHandler)</code>.</p>
  
  <p>I want to test that the handler gets called. Of course, the dockerclient handles the events in a goroutine.</p>
  
  <p>For now, my handler just spits out a log. If I wait in my test, everything is handled. If I do not, it exits before it handles anything:</p>
  
  <pre><code>func eventCallback(event *dockerclient.Event, ec chan error, args ...interface{}) {
    log.Printf("Received event: %#v\n", *event)
  }
  </code></pre>
  
  <p>My test seems straightforward:</p>
  
  <pre><code>func TestReceiveEvent(t *testing.T) {
     createAndMonitorEvents(server.URL)
     &lt;- eventReady
     eventWriter.Write([]byte(someEvent))
     // test for something here
  }
  </code></pre>
  
  <p>Of course, it doesn't work unless I put in a <code>time.Sleep()</code> because of the goroutine. </p>
  
  <p>How do I tell my test, "wait for the other routine to do its work before running the test", other than putting in some arbitrary sleep? I am looking to test that the event is processed correctly by my handler.</p>
  
  <p>The alternate interface, <code>client.MonitorEvents()</code> returns a channel, which gives me greater control, but the receive off the channel spits out infinite <code>nil</code> events.</p>
  
  <p>UPDATE:</p>
  
  <p>As requested, createAndMonitorEvents is:</p>
  
  <pre><code>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(&amp;e.Event, nil)
      }
      fmt.Println("monitor in place")
    }()
  }
  </code></pre>