Skip to content

Mocks and Stubs — Specification

← Back

This page collects authoritative references for Go test-double tooling: package paths, versioning notes, key APIs, command-line flags, and the fork history that sometimes confuses newcomers (golang/mock is archived; the active fork is go.uber.org/mock). Nothing here is invented; every package listed is real and discoverable via go doc or its README.

Table of Contents

  1. Standard library — testing
  2. github.com/stretchr/testify/mock
  3. github.com/vektra/mockery
  4. go.uber.org/mock (formerly github.com/golang/mock)
  5. github.com/jarcoal/httpmock
  6. net/http/httptest
  7. github.com/DATA-DOG/go-sqlmock
  8. Fork history and lineage
  9. Compatibility matrix

Standard library — testing

The testing package itself does not provide a mock framework. It provides only:

  • *testing.T for assertions, t.Helper() for cleaner failure traces.
  • t.Cleanup(func()) (Go 1.14+) for deterministic teardown — useful to reset mock state.
  • t.TempDir() for filesystem fakes.

Everything else — assert, mock, require — lives in third-party packages. This is intentional. Go's standard library treats test doubles as a style question, not a framework one.

Relevant doc anchors:


github.com/stretchr/testify/mock

Part of the testify suite. Provides a reflection-based mock object with expectation recording.

Core API:

type Mock struct { ... }

func (m *Mock) On(method string, arguments ...interface{}) *Call
func (m *Mock) Called(args ...interface{}) Arguments
func (m *Mock) AssertExpectations(t TestingT) bool
func (m *Mock) AssertCalled(t TestingT, method string, args ...interface{}) bool
func (m *Mock) AssertNumberOfCalls(t TestingT, method string, n int) bool

The Call returned by On supports chaining:

  • .Return(values...) — what the mock returns.
  • .Times(n) — exact call count.
  • .Once(), .Twice() — sugar for Times(1), Times(2).
  • .Run(func(args mock.Arguments)) — side-effect closure invoked on call.
  • .Maybe() — optional call, does not fail AssertExpectations if not invoked.
  • .NotBefore(other *Call) — basic ordering constraint.

Argument matchers:

  • mock.Anything — wildcard.
  • mock.AnythingOfType("string") — typed wildcard.
  • mock.MatchedBy(func(x T) bool { ... }) — predicate.

Caveats:

  • Mock.On registers a regex-free literal-string match on the method name. Typos compile silently.
  • The mock relies on reflection at call sites — there is no compile-time type checking of arguments.
  • Pre-v2, the import path is github.com/stretchr/testify. There is a v2 planning issue; check the repository before pinning.

Reference: https://pkg.go.dev/github.com/stretchr/testify/mock


github.com/vektra/mockery

A code generator that produces testify/mock-compatible mocks from interface declarations.

Two operating modes:

  1. Legacy / CLI flagsmockery --name MyInterface --dir ./internal/repo --output ./mocks.
  2. .mockery.yaml (v2.20+, strongly recommended) — declarative configuration.

Example .mockery.yaml:

with-expecter: true
dir: "mocks/{{.PackagePath}}"
filename: "{{.InterfaceName}}.go"
mockname: "{{.InterfaceName}}"
outpkg: "mocks"
packages:
  github.com/me/app/internal/repo:
    interfaces:
      UserRepo:
      OrderRepo:

Selected flags / config keys:

Key Effect
with-expecter Generates a type-safe EXPECT() wrapper around On calls.
inpackage Emit mocks into the source package (test-only file).
outpkg Mock package name.
srcpkg Source package import path.
case snake or camel for filenames.
boilerplate-file Prepend a license header to generated files.
disable-version-string Omit the Code generated by mockery v... line.

Generated mocks embed mock.Mock so they remain testify-compatible.

Reference: https://vektra.github.io/mockery/


go.uber.org/mock (formerly github.com/golang/mock)

golang/mock was archived in June 2023 by the Go team. The community-maintained fork is go.uber.org/mock, with identical API and tool name mockgen.

Generate:

mockgen -source=repo.go -destination=mocks/repo_mock.go -package=mocks
# or reflect mode:
mockgen -destination=mocks/repo_mock.go github.com/me/app/internal/repo UserRepo,OrderRepo

Two generation modes:

  • Source mode (-source): parses one file, generates mocks for every interface in it. Fast, no dependencies, but does not resolve transitive types.
  • Reflect mode (positional args): builds a small program that imports the target package and uses reflection to emit a mock. Slower but resolves cross-package types correctly.

Core API used in tests:

ctrl := gomock.NewController(t)
defer ctrl.Finish() // not required in Go 1.14+ because of t.Cleanup
m := mocks.NewMockUserRepo(ctrl)

m.EXPECT().FindByID(gomock.Eq("42")).Return(&User{ID: "42"}, nil).Times(1)
m.EXPECT().Save(gomock.Any()).Return(nil)

Matchers: gomock.Eq, gomock.Any, gomock.Not, gomock.Nil, gomock.AssignableToTypeOf, custom via gomock.Matcher interface.

Ordering:

gomock.InOrder(
    m.EXPECT().Begin(),
    m.EXPECT().Insert(gomock.Any()),
    m.EXPECT().Commit(),
)

Or .After(otherCall) on a single expectation.

Controller behavior: every unsatisfied expectation fails the test at Finish time; unexpected calls fail immediately. Since v1.5 (Uber fork), gomock.NewController(t) automatically registers a Cleanup so Finish is implicit.

Reference: https://pkg.go.dev/go.uber.org/mock/gomock


github.com/jarcoal/httpmock

Replaces the default http.DefaultTransport (or a specific *http.Client's transport) with a registry of responders.

httpmock.Activate()
defer httpmock.DeactivateAndReset()

httpmock.RegisterResponder("GET", "https://api.example.com/users/1",
    httpmock.NewStringResponder(200, `{"id":1}`))

Notable APIs:

  • httpmock.ActivateNonDefault(client) — scope to a specific *http.Client.
  • httpmock.NewJsonResponder(status, body) — JSON helper.
  • httpmock.RegisterRegexpResponder — pattern URLs.
  • httpmock.GetCallCountInfo() — assertion on how many times each responder fired.

Caveat: it monkey-patches the transport. In parallel tests sharing http.DefaultTransport this leaks; prefer ActivateNonDefault with an injected client.

Reference: https://pkg.go.dev/github.com/jarcoal/httpmock


net/http/httptest

Standard-library alternative for HTTP integration:

srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(200)
    fmt.Fprintln(w, `{"ok":true}`)
}))
defer srv.Close()

Pros: real HTTP, no monkey-patching, parallel-safe. Cons: you write the handler each time.

httptest.NewRecorder() is used to test handlers directly without spinning a server.

Reference: https://pkg.go.dev/net/http/httptest


github.com/DATA-DOG/go-sqlmock

A driver that implements database/sql/driver.Driver and records expectations on SQL statements:

db, mock, err := sqlmock.New()
mock.ExpectQuery("SELECT id, name FROM users WHERE id = ?").
    WithArgs(42).
    WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(42, "Ada"))

Two query-matching modes:

  • sqlmock.QueryMatcherEqual — strict equality.
  • sqlmock.QueryMatcherRegexp (default) — regex match.

Caveats: tests SQL strings, not DB behavior. Does not catch schema mismatches, dialect differences, or transaction-isolation bugs.

Reference: https://pkg.go.dev/github.com/DATA-DOG/go-sqlmock


Fork history and lineage

Repo Status Notes
github.com/golang/mock Archived 2023-06 Maintained by Google, then handed off. Do not use new.
go.uber.org/mock Active Drop-in replacement. Same mockgen binary name. Same API.
github.com/stretchr/testify Active v1 stable; v2 planning.
github.com/vektra/mockery Active v2 stable; v3 in active development as of 2024-2025.
github.com/matryer/moq Active Generates minimal mocks (no framework dependency).
github.com/jarcoal/httpmock Active Stable; widely used.

If you read older blog posts referring to github.com/golang/mock/gomock, mentally substitute go.uber.org/mock/gomock. The import path is the only meaningful difference.


Compatibility matrix

Tool Go min version Generics support Generates code Runtime reflection
Hand-rolled stub any yes (Go 1.18+) no no
testify/mock 1.17+ partial no yes
mockery v2 1.18+ yes (v2.20+) yes uses testify at runtime
gomock (uber) 1.18+ yes (v0.4.0+) yes minimal
moq 1.18+ yes yes no
sqlmock 1.13+ n/a no no
httpmock 1.13+ n/a no no

For new projects in 2024-2026, the typical mainstream choice is either:

  • Hand-rolled stubs for small interfaces, OR
  • mockery + testify/mock for medium codebases with mostly assertion-style tests, OR
  • gomock (uber) for codebases that want strict expectation-style tests with compile-time type safety.

Avoid mixing two mock frameworks in the same package; readers should not have to context-switch between EXPECT() and On() in adjacent files.