Faking a dependency in Go
Depend on an interface and the test supplies its own implementation.
type Store interface {
Save(lang string, tpm int) error
}
func Record(store Store, lang string, tpm int) error {
if tpm <= 0 {
return errors.New("tpm must be positive")
}
return store.Save(lang, tpm)
}
type fakeStore struct {
calls []string
err error
}
func (f *fakeStore) Save(lang string, tpm int) error {
f.calls = append(f.calls, fmt.Sprintf("%s=%d", lang, tpm))
return f.err
}
func TestRecord(t *testing.T) {
fake := &fakeStore{}
if err := Record(fake, "go", 104); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if len(fake.calls) != 1 || fake.calls[0] != "go=104" {
t.Errorf("calls = %v", fake.calls)
}
}
How it works
- The production code never mentions the fake.
- One small interface is easier to fake than a big one.
- Recording calls in the fake is how you assert on them.
Keywords and builtins used here
appenderrorfuncifintinterfacelenreturnstringstructtype
The run, in numbers
- Lines
- 30
- Characters to type
- 622
- Tokens
- 176
- Three-star pace
- 105 tpm
At the three-star pace of 105 tokens a minute, this run takes about 101 seconds.
Step 1 of 3 in Fakes & fixtures, step 5 of 13 in Testing.