A handler test should not fail just because its translation service gains a new language. If the test expects a Dutch request to return 404, adding Dutch to the real service would break the test without changing the handler. Inject a stub instead: a small replacement that returns known results, so the test can focus on the handler’s response. section 6.4
A stub satisfies the dependency’s interface but omits its complicated logic. It can stand in for a service, repository, or utility. Its predictable values make assertions reliable without requiring the external dependency. section 6.4 section 6.8
A translation-service stub
In Go, a test implementation of Translate returns "bar" when the word is "foo" and an empty string otherwise. Injecting it into the handler lets tests check that a found translation produces HTTP 200, while a missing one produces 404. Other cases check the default English language, an explicitly requested language, and normalization of mixed-case "GerMan". section 6.4
Listing 6.10 translate_test.go
type stubbedService struct{} #1
func (s *stubbedService) Translate(word string, language string) string { #2
if word == "foo" { #3
return "bar"
}
return ""
}
func TestTranslateAPI(t *testing.T) {
tt := []struct {
Endpoint string
StatusCode int
ExpectedLanguage string
ExpectedTranslation string
}{
{
Endpoint: "/translate/foo",
StatusCode: 200,
ExpectedLanguage: "english",
ExpectedTranslation: "bar",
},
{
Endpoint: "/translate/foo?language=german",
StatusCode: 200,
ExpectedLanguage: "german",
ExpectedTranslation: "bar",
},
{
Endpoint: "/translate/baz",
StatusCode: 404,
ExpectedLanguage: "",
ExpectedTranslation: "",
},
}
h := rest.NewTranslateHandler(&stubbedService{}) #4
handler := http.HandlerFunc(h.TranslateHandler)
...
}
The listing shows the small Translate implementation beside a table of expected handler responses. The stub controls translation results; the test checks what the handler does with them. section 6.4
Stubs can also hold a place while layers are built. A team can deliver the handler and let consumers begin integration while the business logic is still under development. Keep the replacement simple: stubs are easy to create, but verifying interactions or injecting varied errors takes extra programming. Use a mock when those checks matter, and reconsider the design if test replacements become complicated. section 6.4 section 6.7 section 6.5.2









