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 ↩
@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. TheRunAndReturn
method doesn't define an expectation. In your example, the methodGet
does it, and it acceptsany
.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.