Skip to main content

Functions That Return Errors

Many Go functions return two values: the result and an error. On success the error is nil; on failure the result is a zero value and the error explains what went wrong.

A test for such a function must check both paths: the good input returns the right value and a nil error, and the bad input actually returns an error — a function that silently accepts bad input is a bug too.


The Good Path

For a valid input, check the error first: if it is not nil, something is deeply wrong and checking the value makes no sense — that is a job for t.Fatalf. Then compare the value.

Valid input, nil error

SafeDivide(10, 2) must return 5 and no error. The error is checked first with t.Fatalf; only then is the value compared.

Prompt
Write a Go test file with a SafeDivide function that returns a float64 result and an error (error when dividing by zero). Write a test for the good path: SafeDivide(10, 2) must return 5 and a nil error — check the error first with t.Fatalf, then the value with t.Errorf. Show the go test -v output.
Output: Go test file and captured go test output
Valid input, nil error

The Bad Path

The other half of the contract: bad input must produce an error. The test calls the function with the bad input and fails if the error is nil.

The result value is ignored with _ — when an error comes back, the value carries no meaning.

Bad input must return an error

Dividing by zero has to fail. If err comes back nil, the test fails with t.Fatal — the function accepted input it should have rejected.

Prompt
Write a Go test for the bad path of SafeDivide: calling it with divisor 0 must return an error. Ignore the value with the blank identifier and fail with t.Fatal if the error is nil. Show the go test -v output.
Output: Go test file and captured go test output
Bad input must return an error

A Table with wantErr

Both paths fit into one table-driven test: give each case a wantErr field saying whether an error is expected.

The loop checks the error side first — got an error when none was expected, or no error when one was expected, is fatal for that subtest. For the good cases it then compares the value as usual.

Good and bad cases in one table

Four cases: three normal divisions and one division by zero with wantErr: true. One loop covers the whole contract of the function.

Prompt
Write a table-driven Go test for SafeDivide where each case has a name, the two inputs, the expected value and a wantErr bool. Use t.Run subtests; fail fatally when the error side does not match wantErr, and compare the value only for cases without an expected error. Include three normal cases and one division by zero. Show the go test -v output.
Output: Go test file and captured go test output
Good and bad cases in one table