Mockery¶
Features for template: testify
.
Choosing this template will render a traditional "mockery-style" template. The section below shows what will be rendered for the given interface.
Description¶
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery
package test
import (
mock "github.com/stretchr/testify/mock"
)
// NewRequester creates a new instance of Requester. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewRequester (t interface {
mock.TestingT
Cleanup(func())
}) *Requester {
// ...
}
// Requester is an autogenerated mock type for the Requester type
type Requester struct {
mock.Mock
}
type Requester_Expecter struct {
mock *mock.Mock
}
func (_m *Requester) EXPECT() *Requester_Expecter {
// ...
}
// Get provides a mock function for the type Requester
func (_mock *Requester) Get(path string) (string, error) {
// ...
}
// Requester_Get_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Get'
type Requester_Get_Call struct {
*mock.Call
}
// Get is a helper method to define mock.On call
// - path
func (_e *Requester_Expecter) Get(path interface{}, ) *Requester_Get_Call {
// ...
}
func (_c *Requester_Get_Call) Run(run func(path string)) *Requester_Get_Call {
// ...
}
func (_c *Requester_Get_Call) Return(s string, err error) *Requester_Get_Call {
// ...
}
func (_c *Requester_Get_Call) RunAndReturn(run func(path string)(string, error)) *Requester_Get_Call {
// ...
}
As you can see, this mock utilizes github.com/stretchr/testify
under the hood and registers call expectations with testify. When the mock receives a call to Get()
, it retrieves the expected value from testify to be returned.
This style of mock also has other interesting methods:
Run a side effect when the argument matches.
func TestRequesterMockRun(t *testing.T) {
m := NewMockRequester(t)
m.EXPECT().Get(mock.Anything).Return("", nil)
m.EXPECT().Get(mock.Anything).Run(func(path string) {
fmt.Printf("Side effect! Argument is: %s", path)
})
retString, err := m.Get("hello")
assert.NoError(t, err)
assert.Equal(t, retString, "")
}
Run a function to perform side-effects, and return the result of the function.
template-data
¶
key | type | description |
---|---|---|
boilerplate-file |
string |
Specify a path to a file that contains comments you want displayed at the top of all generated mock files. This is commonly used to display license headers at the top of your source code. |
mock-build-tags |
"" |
Set the build tags of the generated mocks. Read more about the format. |
unroll-variadic |
bool |
If set to unroll-variadic: true , will expand the variadic argument to testify using the ... syntax. See notes for more details. |
Features¶
Mock Constructors¶
v2.11.0
All mock objects have constructor functions. These constructors do basic test setup so that the expectations you set in the code are asserted before the test exits.
Previously something like this would need to be done:
factory := &mocks.Factory{}
factory.Test(t) // so that mock does not panic when a method is unexpected
defer factory.AssertExpectations(t)
Instead, you may simply use the constructor:
The constructor sets up common functionalities automatically
- The
AssertExpectations
method is registered to be called at the end of the tests viat.Cleanup()
method. - The testing.TB interface is registered on the
mock.Mock
so that tests don't panic when a call on the mock is unexpected.
Expecter Structs¶
v2.10.0 ยท with-expecter: True
Mockery now supports an "expecter" struct, which allows your tests to use type-safe methods to generate call expectations. When enabled through the with-expecter: True
mockery configuration, you can enter into the expecter interface by simply calling .EXPECT()
on your mock object.
For example, given an interface such as
You can use the expecter interface as such:
requesterMock := mocks.NewRequester(t)
requesterMock.EXPECT().Get("some path").Return("result", nil)
A RunAndReturn
method is also available on the expecter struct that allows you to dynamically set a return value based on the input to the mock's call.
requesterMock.EXPECT().
Get(mock.Anything).
RunAndReturn(func(path string) (string, error) {
fmt.Println(path, "was called")
return ("result for " + path), nil
})
Note
Note that the types of the arguments on the EXPECT
methods are interface{}
, not the actual type of your interface. The reason for this is that you may want to pass mock.Any
as an argument, which means that the argument you pass may be an arbitrary type. The types are still provided in the expecter method docstrings.
Return Value Providers¶
v2.20.0
Return Value Providers can be used one of two ways. You may either define a single function with the exact same signature (number and type of input and return parameters) and pass that as a single value to Return
, or you may pass multiple values to Return
(one for each return parameter of the mocked function.) If you are using the second form, for each of the return values of the mocked function, Return
needs a function which takes the same arguments as the mocked function, and returns one of the return values. For example, if the return argument signature of passthrough
in the above example was instead (string, error)
in the interface, Return
would also need a second function argument to define the error value:
First form:
proxyMock := mocks.NewProxy(t)
proxyMock.On("passthrough", mock.AnythingOfType("context.Context"), mock.AnythingOfType("string")).
Return(
func(ctx context.Context, s string) (string, error) {
return s, nil
}
)
Second form:
proxyMock := mocks.NewProxy(t)
proxyMock.On("passthrough", mock.AnythingOfType("context.Context"), mock.AnythingOfType("string")).
Return(
func(ctx context.Context, s string) string {
return s
},
func(ctx context.Context, s string) error {
return nil
},
)
Notes¶
Variadic Arguments¶
Consider if we have a function func Bar(message ...string) error
. A typical assertion might look like this:
We might also want to make an assertion that says "any number of variadic arguments":
However, what we've given to mockery is ambiguous because it is impossible to distinguish between these two intentions:
- Any number of variadic arguments of any value
- A single variadic argument of any value
This is fixed in #359 where you can provide unroll-variadic: False
to get back to the old behavior. Thus, if you want to assert (1), you can then do:
If you want to assert (2), you must set unroll-variadic: True
. Then this assertion's intention will be modified to mean the second case:
An upstream patch to testify
is currently underway to allow passing mock.Anything
directly to the variadic slice: https://github.com/stretchr/testify/pull/1348
If this is merged, it would become possible to describe the above two cases respectively:
// case 1
m.On("Bar", mock.Anything).Return(nil)
// case 2
m.On("Bar", []interface{}{mock.Anything}).Return(nil)
References:
- https://github.com/vektra/mockery/pull/359
- https://github.com/vektra/mockery/pull/123
- https://github.com/vektra/mockery/pull/550
- https://github.com/vektra/mockery/issues/541
Multiple Expectations With Identical Arguments¶
There might be instances where you want a mock to return different values on successive calls that provide the same arguments. For example, we might want to test this behavior:
// Return "foo" on the first call
getter := NewGetter()
assert(t, "foo", getter.Get("key"))
// Return "bar" on the second call
assert(t, "bar", getter.Get("key"))
This can be done by using the .Once()
method on the mock call expectation:
mockGetter := NewMockGetter(t)
mockGetter.EXPECT().Get(mock.anything).Return("foo").Once()
mockGetter.EXPECT().Get(mock.anything).Return("bar").Once()
Or you can identify an arbitrary number of times each value should be returned:
mockGetter := NewMockGetter(t)
mockGetter.EXPECT().Get(mock.anything).Return("foo").Times(4)
mockGetter.EXPECT().Get(mock.anything).Return("bar").Times(2)
Note that with proper Go support in your IDE, all the available methods are self-documented in autocompletion help contexts.