vektra/mockery package allows you to create mocks out of your interface so you can easily mock objects like services and repositories in your unit tests. This is helpful if your application implements dependency injection.
To get started, install mockery: go install github.com/vektra/mockery/v2@latest
You can either call mockery directly or define it in directive. The directive in the comment defines the interface name (--name), source of the interface (--dir) which is currently in the current directory, destination of the generated mocks (--output), and the package name that the mocks will use (--outpkg).
To generate the mocks, run go generate ./.... This scans all your files for any directives.
//go:generate mockery --name=Service --dir=. --output=../../mocks/services --outpkg=servicemock
type Service interface {
GetRows(ctx context.Context) ([]any, error)
}
The generated mock is in Service.go file. GetRows is implemented, and you have a factory function to create an instance of the mock (NewService)
// Code generated by mockery v2.53.5. DO NOT EDIT.
package servicemock
import (
context "context"
mock "github.com/stretchr/testify/mock"
)
// Service is an autogenerated mock type for the Service type
type Service struct {
mock.Mock
}
// GetRows provides a mock function with given fields: ctx
func (_m *Service) GetRows(ctx context.Context) ([]interface{}, error) {
ret := _m.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for GetRows")
}
var r0 []interface{}
var r1 error
if rf, ok := ret.Get(0).(func(context.Context) ([]interface{}, error)); ok {
return rf(ctx)
}
if rf, ok := ret.Get(0).(func(context.Context) []interface{}); ok {
r0 = rf(ctx)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]interface{})
}
}
if rf, ok := ret.Get(1).(func(context.Context) error); ok {
r1 = rf(ctx)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// NewService creates a new instance of Service. 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 NewService(t interface {
mock.TestingT
Cleanup(func())
}) *Service {
mock := &Service{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}