Skip to content

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

Go
package test

type Requester interface {
    Get(path string) (string, error)
}
YAML
template: testify
packages:
    github.com/vektra/mockery/v3/pkg/fixtures:
        config:
            dir: "{{.InterfaceDir}}"
            filename: "mocks.go"
            pkgname: "test"
            mockname: "Mock{{.InterfaceName}}"
        interfaces:
            Requester:
Go
// 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 {
    // ...
}
Go
package test

import (
    "testing"

    "github.com/stretchr/testify/assert"
)

func TestRequesterMock(t *testing.T) {
    m := NewMockRequester(t)
    m.EXPECT().Get("foo").Return("bar", nil).Once()
    retString, err := m.Get("foo")
    assert.NoError(t, err)
    assert.Equal(t, retString, "bar")
}

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.

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

Go
func TestRequesterMockRunAndReturn(t *testing.T) {
    m := NewMockRequester(t)
    m.EXPECT().Get(mock.Anything).RunAndReturn(func(path string) (string, error) {
        return path + " world", nil
    })
    retString, err := m.Get("hello")
    assert.NoError(t, err)
    assert.Equal(t, retString, "hello world")
}

Because the mock embeds the testify Mock object, you can all any methods on that as well.

Go
func TestRequesterMockTestifyEmbed(t *testing.T) {
    m := NewMockRequester(t)
    m.EXPECT().Get(mock.Anything).Return("", nil).Twice()
    m.Get("hello")
    m.Get("world")
    assert.Equal(t, len(m.Mock.Calls), 2)
}

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:

Go
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:

Go
factory := mocks.NewFactory(t)

The constructor sets up common functionalities automatically

  • The AssertExpectations method is registered to be called at the end of the tests via t.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

Go
type Requester interface {
    Get(path string) (string, error)
}

You can use the expecter interface as such:

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

Go
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:

Go
type Proxy interface {
    passthrough(ctx context.Context, s string) (string, error)
}

First form:

Go
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:

Go
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:

Go
func TestFoo(t *testing.T) {
  m := NewMockFoo(t)
  m.On("Bar", "hello", "world").Return(nil)

We might also want to make an assertion that says "any number of variadic arguments":

Go
m.On("Bar", mock.Anything).Return(nil)

However, what we've given to mockery is ambiguous because it is impossible to distinguish between these two intentions:

  1. Any number of variadic arguments of any value
  2. 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:

Go
m.On("Bar", mock.Anything).Return(nil)

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:

Go
m.On("Bar", mock.Anything).Return(nil)

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:

Go
// case 1
m.On("Bar", mock.Anything).Return(nil)
// case 2
m.On("Bar", []interface{}{mock.Anything}).Return(nil)

References:

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:

Go
// 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:

Go
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:

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