liveBook · Manning

Stub

As explained in Shipping Go: Develop, deliver, discuss, design, and go again

A stub is a test replacement for a dependency that returns predetermined results without reproducing the dependency's full behavior.

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

How Shipping Go: Develop, deliver, discuss, design, and go again covers it

How deep it goes
Defines stubs as simple implementations and works through handler response tests; leaves interaction and error verification to mocks.
Examples
Uses a Go translation stub returning "bar" for "foo" and handler tests for success, missing translations, and language handling.
What it assumes
Assumes familiarity with Go handlers and tests while explaining why an injected interface makes a dependency replaceable.
What you can do after
Build it from scratch as an injected Go dependency to test handler responses independently of the real service.
How it connects
Connects stubs to interfaces, dependency injection, unit tests, mocks, fakes, and the testing pyramid.

Also explained in

Compare how 10 books explain stub →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Shipping Go: Develop, deliver, discuss, design, and go again. The section links point to the parts of the book it draws on.