How do you mock dependencies in Go without a mocking framework? Where should the interface live?
Question 384MediumGo 1.22 to 1.25
Go's implicit interface satisfaction lets the consumer define a small interface describing only what it needs; production code passes the real type, tests pass a hand-written fake. "Accept interfaces, return structs."
// in package billing (the consumer)
type PaymentGateway interface {
Charge(ctx context.Context, customerID string, cents int64) (string, error)
}
type Service struct{ gw PaymentGateway }
func (s *Service) Checkout(ctx context.Context, id string, cents int64) error {
if cents <= 0 {
return errors.New("invalid amount")
}
_, err := s.gw.Charge(ctx, id, cents)
return err
}
// in billing_test.go
type fakeGateway struct {
calls []int64
err error
}
func (f *fakeGateway) Charge(_ context.Context, _ string, cents int64) (string, error) {
f.calls = append(f.calls, cents)
return "txn_1", f.err
}
func TestCheckoutPropagatesError(t *testing.T) {
fg := &fakeGateway{err: errors.New("declined")}
s := &Service{gw: fg}
if err := s.Checkout(t.Context(), "c1", 500); err == nil {
t.Fatal("want error")
}
if len(fg.calls) != 1 || fg.calls[0] != 500 {
t.Fatalf("calls = %v", fg.calls)
}
}
Interviewer is looking for: small interfaces (1–3 methods) defined at the point of use, not a giant interface exported next to the implementation "for mocking." Prefer fakes (working in-memory implementations) over strict call-order mocks — they're less brittle. Tools like gomock/mockery are fine for big surfaces, but over-mocking tests implementation rather than behavior. For time, inject a func() time.Time or use synctest.
More on Performance, Profiling & Testing
- Q382How does native fuzzing work in Go? Write a fuzz test and explain the corpus.
- Q383What is testing/synctest and what problem does it solve?
- Q385How do you test HTTP handlers and HTTP clients with net/http/httptest?
- Q386How does test coverage work in Go? Explain covermode, -coverpkg, and coverage for integration tests.
- Q387What is Profile-Guided Optimization (PGO) in Go, and how do you use it?
- Q388How does inlining work in the Go compiler, how do you inspect it, and what prevents a function from being inlined?