A test helper is supporting test code that removes repetitive setup or captures behavior for validation. In Go, an interface-compatible helper can replace an external destination, while a helper function can construct valid test inputs and stop immediately when setup fails. section 4.3.2 section 6.2.6
Common patterns include:
- Implement io.Writer with a small struct that stores written bytes or strings, then pass it to the logger through its output option. section 4.3.2
- Compare captured output with expected messages across logging levels, using a table-driven test rather than checking standard output. section 4.3.2
- Wrap chained builders such as ParseDecimal, ParseCurrency, and NewAmount in must-style helpers that call t.Helper and t.Fatal on invalid setup. section 6.2.6
Capture logger output
Define testWriter with a contents field and a Write method that appends the byte slice as a string and returns its length. Construct the logger with this writer, invoke its logging methods, and compare contents with the expected output.
Listing 6.16 convert_test.go: Helpers to parse Currency and Amount
package money_test
import (
"testing"
"learngo-pockets/moneyconverter/money"
)
func mustParseCurrency(t *testing.T, code string) money.Currency {
t.Helper() #1
currency, err := money.ParseCurrency(code)
if err != nil {
t.Fatalf("cannot parse currency %s code", code) #2
}
return currency
}
func mustParseAmount(t *testing.T, value string, code string) money.Amount {
t.Helper() #3
n, err := money.ParseDecimal(value)
if err != nil {
t.Fatalf("invalid number: %s", value)
}
currency, err := money.ParseCurrency(code)
if err != nil {
t.Fatalf("invalid currency code: %s", code)
}
amount, err := money.NewAmount(n, currency)
if err != nil {
t.Fatalf("cannot create amount with value %v and currency code %s",
n, code)
}
return amount
}
The helper listing shows how t.Helper preserves the failing test location while t.Fatal prevents tests from continuing with invalid values. section 6.2.6
