Skip to content

Instantly share code, notes, and snippets.

@maratori
Last active May 31, 2025 19:08
Show Gist options
  • Save maratori/8772fe158ff705ca543a0620863977c2 to your computer and use it in GitHub Desktop.
Save maratori/8772fe158ff705ca543a0620863977c2 to your computer and use it in GitHub Desktop.
Comparison of golang mocking libraries

Comparison of golang mocking libraries

Updated 2025-05-31

gomock testify + mockery mockio minimock moq

Library

GitHub stars s1 s2 + s3 s4 s5 s6
Latest release date d1 d2 + d3 d4 d5 d6
Maintained
Notes 1 2 3

Mock creation

Code generation 4 5
Works without code generation 6
Use t.Cleanup() 7
Support generics

DSL

Execute custom func 8
Calls order 9
Wait for time.Duration 10
Wait for message from chan 11
Panic 12
Assert expectations with timeout
Return zero values by default 13
Capturer 14

Calls count

Exact calls count 15
Min/max calls count 16
Called at least once
Don't check calls count
Expect once by default 17

Matchers

Any value
Equal to (reflect)
Not equal to
Exact (==)
One of values
Regex
Substring
Is nil
Not nil
Type is
Length is ✔️ 18
Slice elements in any order
Slice contains
Map contains keys
Functional options
Logical operations on matchers
Custom matcher

Examples

gomock

func TestUberGomock(t *testing.T) {
	ctrl := gomock.NewController(t)
	m := NewMockMyInterface(ctrl)
	gomock.InOrder(
		m.EXPECT().Method(gomock.Any(), "abc").Return(123, nil),
		m.EXPECT().AnotherMethod(gomock.Any(), gomock.Len(3)),
	)
	...
}

testify/mock + mockery

func TestTestifyMock(t *testing.T) {
	m := mocks.NewMyInterface(t)
	m.EXPECT().Method(mock.Anything, "abc").After(5*time.Second).Return(123, nil).Once()
	m.EXPECT().AnotherMethod(mock.Anything, "abc").Return(0, nil).Once()
	...
}

mockio

func TestMockio(t *testing.T) {
	ctrl := mock.NewMockController(t, mockopts.StrictVerify())
	m := mock.Mock[MyInterface](ctrl)
	mock.WhenDouble(m.Method(mock.AnyContext(), mock.Equal("abc"))).ThenReturn(123, nil).Verify(mock.Once())
	mock.WhenDouble(m.AnotherMethod(mock.AnyContext(), mock.Regex("ab?c"))).Verify(mock.Once())
	captor := mock.Captor[string]()
	mock.WhenDouble(m.Method(mock.AnyContext(), captor.Capture()))
	...
	assert.Equal(t, "abc", captor.Last())
}

minimock

func TestMinimock(t *testing.T) {
	ctrl := minimock.NewController(t)
	m := NewMyInterfaceMock(ctrl)
	m.MethodMock.When(minimock.AnyContext, "abc").Then(123, nil)
	m.AnotherMethodMock.When(minimock.AnyContext, "abc").Then(0, nil)
	...
}

moq

func TestMoq(t *testing.T) {
	m := MyInterfaceMock{
		MethodFunc: func(ctx context.Context, s string) (int, error) {
			assert.Equal(t, "abc", s)
			return 123, nil
		},
		AnotherMethodFunc: func(ctx context.Context, s string) (int, error) {
			assert.Len(t, s, 1)
			return 0, nil
		},
	}
	t.Cleanup(func() {
		assert.Len(t, m.MethodCalls(), 1)
		assert.Len(t, m.AnotherMethodCalls(), 1)
	})
	...
}

Footnotes

  1. Google stopped maintaining the original gomock with 9K stars, Uber forked it and continue development

  2. mockery/v3, became a generic interface-based code generation framework, see blog post

  3. mockio supports only amd64 and arm64 processors and it heavily depends on compiler internals and unsafe package, see docs

  4. CLI tool to auto generate mocks from interfaces

  5. While mockio/v2 is designed to work without code generation, it also provides a template for mockery/v3, see docs

  6. Create mocks in runtime, without code generation

  7. Mock constructor uses t.Cleanup() to assert expectations after test by default

  8. Use arbitrary function to execute, allowing to implement any feature in the table

  9. Define expected order of calls

  10. Block execution of method using time.Sleep()

  11. Block execution of method using <- channel

  12. Panic instead of method execution

  13. Not defining return values leads to returning zero values

  14. Ability to capture actual call arguments to validate them later (not in mock)

  15. Define expected exact number of calls in test

  16. Define expected min/max number of calls in test

  17. Not defining number of calls leads to expectation that method to be called once

  18. There are only length matchers for slices and maps, not for strings

@maratori
Copy link
Author

@m1khal3v @Zurvarian I've added mockio to the table

@mbalabin
Copy link

Hi, thanks for your great comparison.

Just a small correction: minimock has a "Capturer" capability. All call parameters are stored in a mock and may be accessed later via Calls() function.

@maratori
Copy link
Author

maratori commented Sep 1, 2024

@mbalabin good catch, thanks! Actually, all libs but gomock allow introspecting calls afterward. IMO, mockio provides the best API for that, but I've updated the table accordingly.

@ovechkin-dm
Copy link

ovechkin-dm commented Sep 1, 2024

@m1khal3v @Zurvarian I've added mockio to the table

Thank you for adding mockio to your table.
The feature set for it is very accurate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment