Updated 2024-05-29
Uber gomock |
testify + mockery | minimock | moq | Google gomock |
|
---|---|---|---|---|---|
GitHub stars | |||||
Latest release date | |||||
Maintained | ✅ | ✅ | ✅ | ✅ | ❌ |
Code generation 1 | ✅ | ✅ | ✅ | ✅ | ✅ |
Not only code generation 2 | ❌ | ✅ | ❌ | ❌ | ❌ |
Use t.Cleanup() 3 |
✅ | ✅ | ✅ | ❌ | ✅ |
Support generics | ✅ | ✅ | ✅ | ✅ | ❌ |
Execute custom func 4 | ✅ | ✅ | ✅ | ✅ | ✅ |
Typed expected arguments 5 | ✖️ | ✖️ | ✔️ | ✔️ | ✖️ |
Typed returned values 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 | ✅ | ❌ | ❌ | ❌ | ✅ |
Exact calls count 12 | ✅ | ✅ | ✅ | ❌ | ✅ |
Min/max calls count 13 | ✅ | ❌ | ❌ | ❌ | ✅ |
Called at least once | ✅ | ❌ | ❌ | ❌ | ✅ |
Don't check calls count | ✅ | ✅ | ✅ | ❌ | ✅ |
Expect once by default 14 | ✅ | ❌ | ❌ | ❌ | ✅ |
Any value | ✅ | ✅ | ✅ | ❌ | ✅ |
Equal to | ✅ | ✅ | ✅ | ❌ | ✅ |
Regex | ✅ | ❌ | ❌ | ❌ | ❌ |
Not equal to | ✅ | ❌ | ❌ | ❌ | ✅ |
Is nil |
✅ | ❌ | ❌ | ❌ | ✅ |
Type is | ✅ | ✅ | ❌ | ❌ | ✅ |
Length is | ✅ | ❌ | ❌ | ❌ | ✅ |
Slice elements in any order | ✅ | ❌ | ❌ | ❌ | ✅ |
Compose matchers with logical or | ✅ | ❌ | ❌ | ❌ | ❌ |
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 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)
})
...
}
func TestGoogleGomock(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)),
)
...
}
Footnotes
-
CLI tool to auto generate mocks from interfaces ↩
-
Allow writing mock manually, 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 ↩
-
Defining expected arguments in test doesn't rely on
any
(aka emptyinterface{}
) ↩ -
Defining returned values (with methods like
Return
andDoAndReturn
) in test doesn't rely onany
(aka emptyinterface{}
) ↩ -
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 ↩
-
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 ↩
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.