An atomic test checks one behavior through the smallest useful boundary. In a translation service, call Translate directly instead of routing through the HTTP handler, so failures point more clearly to service logic. section 6.3
Use the boundary that matches the behavior under test:
- Test translation behavior directly with the service and a table of word-language cases. section 6.3
- Test request handling separately through the handler when the behavior involves HTTP translation requests. section 6.3
- Inject the service into the handler so each test can exercise the intended component without changing the surrounding design. section 6.3
Service test versus API test
TestTranslate constructs a StaticService and calls Translate for each table row. TestTranslateAPI instead constructs a handler and exercises the HTTP-facing path. The first test isolates translation behavior; the second checks the assembled API boundary. section 6.3
Listing 6.9 translate_test.go
func TestTranslate(t *testing.T) {
...
underTest := translation.NewStaticService() #1
for _, test := range tt {
// Act
res := underTest.Translate(test.Word, test.Language) #2
...
}
}
The table-driven service test provides a compact template for exercising one operation across multiple inputs. section 6.3
