A channel does not automatically make goroutines meet at a known point, and a mutex does not tell a test that background work has finished. Synchronization depends on the guarantee needed: exclusive access to shared state or a rendezvous between goroutines. section 8.3 section 9.7
Choose the mechanism by the interaction:
- When parallel goroutines access or mutate a shared resource, use a mutex to keep them out of the critical section at the same time. section 8.3
- When one stage must signal another or transfer ownership of a ready resource, use a channel. An unbuffered send waits for a receiver, giving both goroutines a rendezvous. section 8.3 section 9.7
- Do not treat a buffered send as a rendezvous. It can complete while space remains, without a receiver being ready; it blocks only when the buffer is full. section 9.7
ch3 := make(chan int, 1) ch3 <-1 #1 ch3 <-2 #2
With capacity one, the first send can proceed without a receiver. The second blocks because the buffer is full—not because every send synchronizes with a receive. section 9.7
An asynchronous test that sleeps
A handler starts a goroutine that calls a publisher. A mock can protect its recorded value with sync.RWMutex, yet a test that sleeps briefly before reading it may still run before publication. The lock protects access; the sleep does not establish completion. Instead, have the mock send the published value on an unbuffered channel and let the test receive before asserting. A select with time.After can bound the wait if publication fails. If direct synchronization is unavailable, retrying the assertion is preferable to one passive sleep. section 11.5
type publisherMock struct {
ch chan []Foo
}
func (p *publisherMock) Publish(got []Foo) {
p.ch <- got #1
}
func TestGetBestFoo(t *testing.T) {
mock := publisherMock{
ch: make(chan []Foo),
}
defer close(mock.ch)
h := Handler{
publisher: &mock,
n: 2,
}
foo := h.getBestFoo(42)
// Check foo
if v := len(<-mock.ch); v != 2 { #2
t.Fatalf("expected 2, got %d", v)
}
}
The publisher mock sends the received slice to the test, which waits for it before checking its length. section 11.5










