We can all agree that TDD is the bees knees, right? Something that can trip newbies up with golang is writing tests against a function that has a timeout.
Often when waiting for a result over a channel, it can make sense to add a timeout so we don't wait forever. Consider the following code
func doSomething(done chan struct{}) {
// simulate an operation that takes too long
time.Sleep(time.Second * 5)
done <- struct{}
}
// We need to test this
func MyCode() {
c := make(chan struct{})
select {
case <- done:
// hurray!
case <- time.After(time.Second * 5)
// oh no!
}
Writing a unit test that exercises our timeout logic and doesn't take 5 seconds to run can seem difficult at first, but it is actually quite simple. We can use something called remote function overriding to declare a variable that we can override in our test.
var after = time.After
And our switch statement changes like so
select {
case <- done:
// hurray!
case <- after(time.Second * 5)
// oh no!
}
Now, in our tests, we can easily change the definition of after, to make it happen instantly
func TestSomething(t *testing.T) {
after = func(d time.Duration) <-chan time.Time {
return time.After(0)
}
// your test code here
}
Top comments (0)