Skip to content

Instantly share code, notes, and snippets.

@maratori
Last active April 9, 2026 07:40
Show Gist options
  • Select an option

  • Save maratori/8772fe158ff705ca543a0620863977c2 to your computer and use it in GitHub Desktop.

Select an option

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 ↩

@arshamalh

Copy link
Copy Markdown

Now gomock is not maintained anymore and we can use its forked version by Uber instead, which might have different features than the one mentioned in this table.

@maratori

Copy link
Copy Markdown
Author

@arshamalh thanks for pointing this out. I need some time to check it and update the table.

@maratori

Copy link
Copy Markdown
Author

@arshamalh I've added Uber's gomock to the table

@Zurvarian

Copy link
Copy Markdown

Hi, thanks for this table, it is quite helpful.

There is another, quite new, mocking library that I've been evaluating for our projects that is quite promising too, in case you want to consider it: https://github.com/ovechkin-dm/mockio

It is still not well known, but what I've tested so far works fine and the fact that it does not require mock generation is quite helpful.

@unmarshall

Copy link
Copy Markdown

testify column needs correction in the matchers section. Using assert you can check nil (assert.Nil and assert.NotNil), similarly assert.Len to check the length, assert.NotEqual. For regular expressions (https://pkg.go.dev/github.com/pgpst/pgpst/internal/github.com/stretchr/testify/assert#Regexp). The comparison is quite nice and provides one pager comparison but needs to be updated so that one can rely upon it.

@maratori

maratori commented Jan 8, 2024

Copy link
Copy Markdown
Author

@unmarshall correct me if I'm wrong, but you can't use functions from the assert package as matchers for the mock package.

@maratori

maratori commented Jan 8, 2024

Copy link
Copy Markdown
Author

@Zurvarian mockio looks really interesting, thanks! I need to think if it's mature enough to add it to the table.

@unmarshall

Copy link
Copy Markdown

@maratori Ah you are right.
There is another framework which has received attention: https://github.com/vektra/mockery

@maratori

maratori commented Jan 9, 2024

Copy link
Copy Markdown
Author

@unmarshall mockery is already on the table.

@LandonTClipp

Copy link
Copy Markdown

Maintainer of mockery here. The table lists mockery has not having Typed expected arguments (with the strict requirement here being that we don't use interface{}). There is a way to utilize strictly type-equivalent assertions through .RunAndReturn, see here: https://vektra.github.io/mockery/latest/features/#expecter-structs

Example:

requesterMock.EXPECT().
    Get(mock.Anything).
    RunAndReturn(func(path string) string { 
        fmt.Println(path, "was called")
        return "result for " + path
    })

I intend v3 to address the "various ways to assert the same expectation" issue, but just an FYI that mockery does in fact allow this particular pattern.

@maratori

maratori commented Jan 11, 2024 •

Copy link
Copy Markdown
Author

@LandonTClipp, thanks for pointing me this. Most probably, the wording in the table needs to be better. Typed expected arguments means that a method to define expectation is typed. The RunAndReturn method doesn't define an expectation. In your example, the method Get does it, and it accepts any.

But I've removed the wrong checkmark in Uber gomock for that feature.

Actually, I realized that having Typed expected arguments means not having matches at all.

UPD: The last statement is incorrect as mockio has matchers, and it's strictly typed at the same time.

@LandonTClipp

Copy link
Copy Markdown

Theoretically, setting all elements to mock.Anything to the argument matcher, then using .RunAndReturn has the effect of a totally type-safe expectation. This is kind of the style of matryer/moq, just done in a different way.

It's for sure a hard thing to categorize correctly :D

@m1khal3v

Copy link
Copy Markdown

Hi, thanks for this table, it is quite helpful.

There is another, quite new, mocking library that I've been evaluating for our projects that is quite promising too, in case you want to consider it: https://github.com/ovechkin-dm/mockio

It is still not well known, but what I've tested so far works fine and the fact that it does not require mock generation is quite helpful.

It’s strange that it’s still not in the table. great library without code generation

@maratori

Copy link
Copy Markdown
Author

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

@mbalabin

Copy link
Copy Markdown

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

maratori commented Sep 1, 2024

Copy link
Copy Markdown
Author

@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

ovechkin-dm commented Sep 1, 2024 •

Copy link
Copy Markdown

@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.

@tmeckel

tmeckel commented Sep 7, 2025

Copy link
Copy Markdown

@maratori great stuff! Thank you ❤️

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