Updated 2024-09-01
gomock | testify + mockery | mockio | minimock | moq | |
---|---|---|---|---|---|
GitHub stars | + | ||||
Latest release date | + | ||||
Maintained | ✅ | ✅ | ✅ | ✅ | ✅ |
Notes | 1 | 2 | |||
Code generation 3 | ✅ | ✅ | ✖️ | ✅ | ✅ |
Works without code generation 4 | ❌ | ✅ | ✅ | ❌ | ❌ |
Use t.Cleanup() 5 |
✅ | ✅ | ✅ | ✅ | ❌ |
Support generics | ✅ | ✅ | ✅ | ✅ | ✅ |
Execute custom func 6 | ✅ | ✅ | ✅ | ✅ | ✅ |
Calls order 7 | ✅ | ✅ | ❌ | ❌ | ❌ |
Wait for time.Duration 8 |
❌ | ✅ | ❌ | ❌ | ❌ |
Wait for message from chan 9 |
❌ | ✅ | ❌ | ❌ | ❌ |
Panic 10 | ❌ | ✅ | ❌ | ❌ | ❌ |
Assert expectations with timeout | ❌ | ❌ | ❌ | ✅ | ❌ |
Return zero values by default 11 | ✅ | ❌ | ✅ | ❌ | ❌ |
Capturer 12 | ❌ | ✅ | ✅ | ✅ | ✅ |
Exact calls count 13 | ✅ | ✅ | ✅ | ✅ | ❌ |
Min/max calls count 14 | ✅ | ❌ | ❌ | ❌ | ❌ |
Called at least once | ✅ | ❌ | ✅ | ❌ | ❌ |
Don't check calls count | ✅ | ✅ | ✅ | ✅ | ❌ |
Expect once by default 15 | ✅ | ❌ | ❌ | ❌ | ❌ |
Any value | ✅ | ✅ | ✅ | ✅ | ❌ |
Equal to (reflect ) |
✅ | ✅ | ✅ | ✅ | ❌ |
Not equal to | ✅ | ❌ | ✅ | ❌ | ❌ |
Exact (== ) |
❌ | ❌ | ✅ | ❌ | ❌ |
One of values | ✅ | ❌ | ✅ | ❌ | ❌ |
Regex | ✅ | ❌ | ✅ | ❌ | ❌ |
Substring | ❌ | ❌ | ✅ | ❌ | ❌ |
Is nil |
✅ | ❌ | ✅ | ❌ | ❌ |
Not nil |
✅ | ❌ | ✅ | ❌ | ❌ |
Type is | ✅ | ✅ | ✅ | ❌ | ❌ |
Length is | ✅ | ❌ | ✔️ 16 | ❌ | ❌ |
Slice elements in any order | ✅ | ❌ | ✅ | ❌ | ❌ |
Slice contains | ❌ | ❌ | ✅ | ❌ | ❌ |
Map contains keys | ❌ | ❌ | ✅ | ❌ | ❌ |
Functional options | ❌ | ✅ | ❌ | ❌ | ❌ |
Logical operations on matchers | ✅ | ❌ | ❌ | ❌ | ❌ |
Custom matcher | ✅ | ✅ | ✅ | ✅ | ❌ |
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)),
)
...
}
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()
...
}
func TestMockio(t *testing.T) {
mock.SetUp(t, mockopts.StrictVerify())
m := mock.Mock[MyInterface]()
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())
}
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)
...
}
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
-
Google stopped maintaining the original gomock with 9K stars, Uber forked it and continue development ↩
-
mockio
supports only amd64 and arm64 processors and it heavily depends on compiler internals and unsafe package ↩ -
CLI tool to auto generate mocks from interfaces ↩
-
Create mocks in runtime, without code generation ↩
-
Mock constructor uses
t.Cleanup()
to assert expectations after test by default ↩ -
Use arbitrary function to execute, allowing to implement any feature in the table ↩
-
Define expected order of calls ↩
-
Block execution of method using
time.Sleep()
↩ -
Block execution of method using
<- channel
↩ -
Panic instead of method execution ↩
-
Not defining return values leads to returning zero values ↩
-
Ability to capture actual call arguments to validate them later (not in mock) ↩
-
Define expected exact number of calls in test ↩
-
Define expected min/max number of calls in test ↩
-
Not defining number of calls leads to expectation that method to be called once ↩
-
There are only length matchers for slices and maps, not for strings ↩
@arshamalh I've added Uber's gomock to the table