Skip to content

Instantly share code, notes, and snippets.

@maratori
Last active April 15, 2025 05:19
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-04-13

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 ✖️
Works without code generation 5
Use t.Cleanup() 6
Support generics

DSL

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

Calls count

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

Matchers

Any value
Equal to (reflect)
Not equal to
Exact (==)
One of values
Regex
Substring
Is nil
Not nil
Type is
Length is ✔️ 17
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, starting from 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. Create mocks in runtime, without code generation

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

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

  8. Define expected order of calls

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

  10. Block execution of method using <- channel

  11. Panic instead of method execution

  12. Not defining return values leads to returning zero values

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

  14. Define expected exact number of calls in test

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

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

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

@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