Suppose a translation handler creates its own translation service. A handler test that expects a missing translation to produce HTTP 404 could break when someone adds that translation. The test is then checking the service’s changing data as well as the handler’s response logic. Dependency injection gives the handler a service from outside, so the test can choose which service it receives. section 6.4
Think of fitting different engines into a car body: the body needs an engine that meets its requirements, not one particular model. In Go, a small interface expresses the requirement. A consuming struct holds that interface, and its constructor accepts a concrete service that satisfies it. The handler calls the interface without needing to know which implementation was supplied. section 6.2 section 6.3
Listing 6.5 translate.go
// TranslateHandler will translate calls for caller.
type TranslateHandler struct {
service Translator #1
}
// NewTranslateHandler will create a new instance of the handler using a
// translation service.
func NewTranslateHandler(service Translator) *TranslateHandler{ #2
return &TranslateHandler{
service: service,
}
}
...
// TranslateHandler will take a given request with a path value of the
// word to be translated and a query parameter of the
// language to translate to.
func (t *TranslateHandler) \
TranslateHandler(w http.ResponseWriter, r *http.Request) { #3
...
translation := t.service.Translate(word, language) #4
...
}
The handler stores a Translator, accepts it through NewTranslateHandler, and calls it when handling a request. section 6.3
To wire the translation endpoint by hand:
- Define the narrow Translator interface around the Translate method the handler needs. section 6.2
- Make StaticService satisfy the interface, then pass it to NewTranslateHandler when setting up the HTTP route. section 6.3
- In handler tests, pass a stub instead of the static service to control the translation returned. section 6.4
Testing the handler without changing the service
A stubbed Translator returns "bar" for "foo" and an empty string otherwise. Injecting it lets a handler test check the expected HTTP 200 response for a found translation and HTTP 404 for a missing one. Adding Dutch translations to the real service no longer changes what that handler test receives. section 6.4
Manual wiring keeps the choice of implementation visible at setup time; Wire, Fx, and Kit are noted as alternatives for wiring dependencies. The practical payoff is a modular service whose parts can be changed and tested independently. Configuration can also work with dependency injection to hide incomplete or untested features. section 6.3 section 8.7 section 11.2




















