Original post

How do you usually deal with testing methods that spawn various goroutines? In the case of a single routine, I’ve seen people suggest returning <-chan struct{} and just <- ch in the test, or select with a timeout.

Great, but what if a method spawns multiple goroutines? Would you pass in a sync.WaitGroup as a parameter? Or internally use a sync.WaitGroup and return a chan that gets closed after waiting for that? Could use a helper like:

type WG struct {
        *sync.WaitGroup
        DoneCh chan struct{}
}

func New() WG {
        return WG{WaitGroup: &sync.WaitGroup{}, DoneCh: make(chan struct{})}
}

func (w WG) Wait() {
        w.WaitGroup.Wait()
        close(w.DoneCh)
}

and in a method do:

func f() (<-chan struct{}, error) {
        w := New()

        w.Add(1)
         func() {
                defer w.Done()
                println("do whatever")
        }()

        w.Add(1)
         func() {
                defer w.Done()
                time.Sleep(1 * time.Second)
                println("do whatever #2")
        }()

         w.Wait()

        return w.DoneCh, nil
}

It seems like a ton of overhead for something that would rarely be checked apart from in testing. Curious how you all approach this.