A struct groups named fields, potentially with different types, into one meaningful Go value. Use one when related data should travel together, such as a test case containing an input language and its expected greeting. section 2.3.2
A struct declaration defines the fields that make up the value:
- Declare a type with type Name struct { ... }. section 2.3.2
- Give each field a name and type, such as lang language and want string. section 2.3.2
- Nest other values, including slices, to model richer data such as a Bookworm with a list of Books. section 3.1.3
- Add JSON tags when field names must correspond to names in JSON; decoded fields must be exposed so encoding/json can write them. section 3.1.3
Table-driven greeting tests
func TestGreet(t *testing.T) { type testCase struct { lang language want string } tests := map[string]testCase{ "English": {lang: "en", want: "Hello world"}, "French": {lang: "fr", want: "Bonjour le monde"}, } for name, tc := range tests { t.Run(name, func(t *testing.T) { got := greet(tc.lang) if got != tc.want { t.Errorf("expected: %q, got: %q", tc.want, got) } }) } } The struct keeps each input and expected output together while a map names each scenario. A similar design models JSON data with Bookworm and Book structs, then decodes into []Bookworm. section 2.3.2 section 3.1.3
Listing 3.4 bookworm.go: Bookworm and Book structures
// A Bookworm contains the list of books on a bookworm's shelf.
type Bookworm struct {
Name string `json:"name"` #1
Books []Book `json:"books"` #2
}
// Book describes a book on a bookworm's shelf.
type Book struct {
Author string `json:"author"`
Title string `json:"title"`
}
Inspect a complete struct definition with exported fields, a nested slice, and JSON tags. section 3.1.3
Listing 2.13 main_internal_test.go: Table-driven tests
func TestGreet(t *testing.T) {
type testCase struct {
lang language
want string
}
var tests = map[string]testCase{ #1
"English": {
lang: "en",
want: "Hello world",
},
"French": {
lang: "fr",
want: "Bonjour le monde",
},
"Akkadian, not supported": {
lang: "akk",
want: `unsupported language: "akk"`,
},
"Greek": {
lang: "el",
want: "Χαίρετε Κόσμε",
},
...
"Empty": {
lang: "",
want: `unsupported language: ""`,
},
}
// range over all the scenarios
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
got := greet(tc.lang) #2
if got != tc.want { #3
t.Errorf("expected: %q, got: %q", tc.want, got)
}
})
}
}
Inspect a runnable table-driven test that stores scenarios as map values of a struct type. section 2.3.2













