Testing
Tips
- Most of the time, it’s pointless to fully check both the returned value and the error—only one of them will be set.
Test tables
Using anonoymous structs and a map is a good pattern.
Go
func TestGameAsk(t *testing.T) {
tt := map[string]struct {
input string
want []rune
}{
"5 characters in english": {
input: "HELLO",
want: []rune("HELLO"),
},
"5 characters in arabic": {
input: "مرحبا",
want: []rune("مرحبا"),
},
}
for name, tc := range tt {
t.Run(name, func(t *testing.T) {
g := New(strings.NewReader(tc.input))
got := g.ask()
if !slices.Equal(got, tc.want) {
t.Errorf("got = %v, want %v", string(got), string(tc.want))
}
})
}
}Test Tables with validator functions
Go
func TestConvert(t *testing.T) {
tt := map[string]struct {
amount money.Amount
to money.Currency
validate func(t *testing.T, got money.Amount, err error)
}{
"34.98 USD to EUR": {
amount: money.Amount{},
to: money.Currency{},
validate: func(t *testing.T, got money.Amount, err error) {
if err != nil {
t.Errorf("expected no error, got %s", err.Error())
}
expected := money.Amount{}
if !reflect.DeepEqual(got, expected) {
t.Errorf("expected %v, got %v", expected, got)
}
},
},
}
for name, tc := range tt {
t.Run(name, func(t *testing.T) {
got, err := money.Convert(tc.amount, tc.to)
tc.validate(t, got, err)
})
}
}