Documentation
¶
Overview ¶
Package testutil collects the small, layer-agnostic helpers every forge test eventually wants — table-driven runners, HTTP response assertions, and a handful of golden-path predicates.
Per-layer harnesses (HTTP handler suites, gnomock-backed integration DBs, mock factories, fixture builders) live next to their domain in the kit, not here:
- Transport (HTTP): go/kit/transport/rest/restest
- Database (integration): go/kit/persistence/sqldb/sqldbtest
- JSON:API encoding: go/kit/jsonapi/jsonapitest
- Generated fixtures: produced by `forge generate fixtures` (§23)
- Mocks: produced by `forge generate mocks` / mockery v3
See docs/cookbook/testing.md for the canonical patterns per layer.
Index ¶
- func AssertJSONBody(t *testing.T, rec *httptest.ResponseRecorder, want any)
- func AssertStatus(t *testing.T, rec *httptest.ResponseRecorder, want int)
- func DecodeJSON[T any](t *testing.T, rec *httptest.ResponseRecorder) T
- func NewJSONRequest(t *testing.T, method, target string, body any) *http.Request
- func TableTest[Case any](t *testing.T, cases []Case, name func(Case) string, ...)
- func TableTestSerial[Case any](t *testing.T, cases []Case, name func(Case) string, ...)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AssertJSONBody ¶
func AssertJSONBody(t *testing.T, rec *httptest.ResponseRecorder, want any)
AssertJSONBody decodes the recorder's body into want's shape and asserts equality. The expected value can be a struct, map, or any JSON-compatible Go value.
func AssertStatus ¶
func AssertStatus(t *testing.T, rec *httptest.ResponseRecorder, want int)
AssertStatus checks the HTTP status without reading the body.
func DecodeJSON ¶
func DecodeJSON[T any](t *testing.T, rec *httptest.ResponseRecorder) T
DecodeJSON decodes the recorder's body into T. Useful when a test wants to inspect specific fields rather than match the full payload.
func NewJSONRequest ¶
NewJSONRequest builds an *http.Request whose body is body marshalled as JSON with the matching Content-Type header. Saves three lines of boilerplate in transport tests.
func TableTest ¶
func TableTest[Case any]( t *testing.T, cases []Case, name func(Case) string, fn func(t *testing.T, c Case), )
TableTest runs a slice of cases as parallel subtests. The kit's convention is: leaf tests run in parallel under -race, with `require` for setup and `assert` for body — TableTest handles the t.Run + t.Parallel boilerplate so the call site stays focused on the cases themselves.
type Case struct {
name string
in, want int
}
cases := []Case{
{"zero", 0, 0},
{"one", 1, 2},
}
testutil.TableTest(t, cases, func(c Case) string { return c.name },
func(t *testing.T, c Case) {
assert.Equal(t, c.want, double(c.in))
})
func TableTestSerial ¶
func TableTestSerial[Case any]( t *testing.T, cases []Case, name func(Case) string, fn func(t *testing.T, c Case), )
TableTestSerial is TableTest without t.Parallel — for cases that share mutable state (file system, env vars, package globals) and must run one at a time. Reach for this only when you've established the shared state is unavoidable; the kit-wide default is parallel.
Types ¶
This section is empty.