diff --git a/v2.49/deprecations/index.html b/v2.49/deprecations/index.html index 782e82e8..289ed0e1 100644 --- a/v2.49/deprecations/index.html +++ b/v2.49/deprecations/index.html @@ -887,8 +887,19 @@
packages
¶To resolve this warning, use the packages
feature:
The packages
feature will be the only way to configure mockery in the future.
issue-845-fix
¶This parameter fixes a somewhat uninteresting, but important issue found in #845.
In short, mockery ignored the outpkg:
parameter if inpackage:
was set to True
. This prevents users
from being able to set alternate package names for their mocks that are generated in the same directory
@@ -896,20 +907,25 @@
issue-845-fix
YAMLall: True
-dir: "{{.InterfaceDir}}"
-mockname: "{{.InterfaceName}}Mock"
-outpkg: "{{.PackageName}}_test"
-filename: "mock_{{.InterfaceName}}_test.go"
-inpackage: True
+YAMLall: True
+dir: "{{.InterfaceDir}}"
+mockname: "{{.InterfaceName}}Mock"
+outpkg: "{{.PackageName}}_test"
+filename: "mock_{{.InterfaceName}}_test.go"
+inpackage: True
The outpkg
parameter would not be respected and instead would be forced to take on the value of "{{.PackageName}}"
.
To remove the warning, you must set:
-YAMLissue-845-fix: True
+
After this is done, mocks generated in the old scheme will properly respect the outpkg:
parameter previously set
if being generated with inpackage: True
.
resolve-type-alias
¶
+
This parameter directs Mockery on whether it should resolve a type alias to its underlying, real
type or if it should generate mocks by referencing. Mockery was changed in #808
to support a new language feature that exposed type aliases in the parsed syntax tree. This meant
diff --git a/v2.49/search/search_index.json b/v2.49/search/search_index.json
index 37931a0c..39c1310e 100644
--- a/v2.49/search/search_index.json
+++ b/v2.49/search/search_index.json
@@ -1 +1 @@
-{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"mockery","text":"
Mockery is a project that creates mock implementations of Golang interfaces. The mocks generated in this project are based off of the github.com/stretchr/testify suite of testing packages.
"},{"location":"#why-mockery","title":"Why mockery?","text":"When you have an interface like this:
db.gotype DB interface {\n Get(val string) string\n}\n
and a function that takes this interface:
db_getter.gofunc getFromDB(db DB) string {\n return db.Get(\"ice cream\")\n}\n
You can test getFromDB
by either instantiating a testing database, or you can simply create a mock implementation of DB
using mockery. Mockery can automatically generate a mock implementation that allows us to define assertions on how the mock was used, what to return, and other useful tidbits. We can add a //go:generate
directive above our interface:
db.go//go:generate mockery --name DB\ntype DB interface {\n Get(val string) string\n}\n
.mockery.yamlinpackage: True # (1)!\nwith-expecter: True # (2)!\ntestonly: True # (3)!\n
- Generate our mocks next to the original interface
- Create expecter methods
- Append
_test.go
to the filename so the mock object is not packaged
Bash$ go generate \n05 Mar 23 21:49 CST INF Starting mockery dry-run=false version=v2.20.0\n05 Mar 23 21:49 CST INF Using config: .mockery.yaml dry-run=false version=v2.20.0\n05 Mar 23 21:49 CST INF Walking dry-run=false version=v2.20.0\n05 Mar 23 21:49 CST INF Generating mock dry-run=false interface=DB qualified-name=github.com/vektra/mockery/v2/pkg/fixtures/example_project version=v2.20.0\n
We can then use the mock object in a test:
db_getter_test.goimport (\n \"testing\"\n\n \"github.com/stretchr/testify/assert\"\n)\n\nfunc Test_getFromDB(t *testing.T) {\n mockDB := NewMockDB(t)\n mockDB.EXPECT().Get(\"ice cream\").Return(\"chocolate\").Once()\n flavor := getFromDB(mockDB)\n assert.Equal(t, \"chocolate\", flavor)\n}\n
"},{"location":"#why-use-mockery-over-gomock","title":"Why use mockery over gomock?","text":" - mockery provides a much more user-friendly API and is less confusing to use
- mockery utilizes
testify
which is a robust and highly feature-rich testing framework - mockery has rich configuration options that allow fine-grained control over how your mocks are generated
- mockery's CLI is more robust, user-friendly, and provides many more options
- mockery supports generics (this may no longer be an advantage if/when gomock supports generics)
"},{"location":"#who-uses-mockery","title":"Who uses mockery?","text":" - Grafana
- Google Skia
- Google Skyzkaller
- Hashicorp
- Uber Cadence
- Jaegertracing
- Splunk kafka-mq-go
-
-
-
- eksctl
-
- Task
-
Get Started
"},{"location":"changelog/","title":"Changelog","text":"This changelog describes major feature additions. Please view the releases
page for more details on commits and minor changes.
"},{"location":"changelog/#v2290-template-functions","title":"v2.29.0
template functions","text":"This release adds a large number of template functions available for use in the packages
templating engine.
"},{"location":"changelog/#v2250-recursive-config","title":"v2.25.0
recursive
config","text":"The recursive
parameter allows mockery to dynamically discover sub-packages when using the packages
config.
"},{"location":"changelog/#v2240-exclude-config","title":"v2.24.0
exclude
config","text":"The exclude
parameter allows you to define subpaths to ignore. This is currently only compatible when using non-packages
config.
"},{"location":"changelog/#v2230-replace-types","title":"v2.23.0
Replace Types","text":"The replace-type
parameter allows adding a list of type replacements to be made in package and/or type names. This can help overcome issues like usage of type aliases that point to internal packages.
"},{"location":"changelog/#v2210-packages-configuration","title":"v2.21.0
: packages
configuration","text":"In this version we release the packages
configuration section. This new parameter allows defining specific packages to generate mocks for, while also giving fine-grained control over which interfaces are mocked, where they are located, and how they are configured. Details are provided here.
Community input is desired before we consider deprecations of dynamic walking (via all: True
): https://github.com/vektra/mockery/discussions/549
"},{"location":"changelog/#v2200-improved-return-value-functions","title":"v2.20.0
: Improved Return Value Functions","text":"Return value functions that return an entire method's return value signature can now be provided.
GoproxyMock := mocks.NewProxy(t)\nproxyMock.On(\"passthrough\", mock.AnythingOfType(\"context.Context\"), mock.AnythingOfType(\"string\")).\nReturn(\n func(ctx context.Context, s string) (string, error) {\n return s, nil\n }\n)\n
You may still use the old way where one function is provided for each return value:
GoproxyMock := mocks.NewProxy(t)\nproxyMock.On(\"passthrough\", mock.AnythingOfType(\"context.Context\"), mock.AnythingOfType(\"string\")).\nReturn(\n func(ctx context.Context, s string) string {\n return s\n },\n func(ctx context.Context, s string) error {\n return nil\n },\n)\n
"},{"location":"changelog/#2190-inpackage-suffix-option","title":"2.19.0
: inpackage-suffix
option","text":"When inpackage-suffix
is set to True
, mock files are suffixed with _mock
instead of being prefixed with mock_
for InPackage mocks
"},{"location":"changelog/#v2160-config-search-path","title":"v2.16.0
: Config Search Path","text":"Mockery will iteratively search every directory from the current working directory up to the root path for a .mockery.yaml
file, if one is not explicitly provided.
"},{"location":"changelog/#v2130-generics-support","title":"v2.13.0
: Generics support","text":"Mocks are now capable of supporting Golang generics.
"},{"location":"changelog/#v2110-mock-constructors","title":"v2.11.0
: Mock constructors","text":"Mockery v2.11 introduces constructors for all mocks. This makes instantiation and mock registration a bit easier and less error-prone (you won't have to worry about forgetting the AssertExpectations
method call anymore).
Before v2.11: Go
factory := &mocks.Factory{}\nfactory.Test(t) // so that mock does not panic when a method is unexpected\ndefer factory.AssertExpectations(t)\n
After v2.11: Go
factory := mocks.NewFactory(t)\n
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.
"},{"location":"changelog/#v2100-expecter-structs","title":"v2.10.0
: Expecter Structs","text":"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 {\n Get(path string) (string, error)\n}\n
You can use the type-safe expecter interface as such: Go
requesterMock := mocks.NewRequester(t)\nrequesterMock.EXPECT().Get(\"some path\").Return(\"result\", nil)\nrequesterMock.EXPECT().\n Get(mock.Anything).\n Run(func(path string) { fmt.Println(path, \"was called\") }).\n // Can still use return functions by getting the embedded mock.Call\n Call.Return(func(path string) string { return \"result for \" + path }, nil)\n
"},{"location":"changelog/#v200-major-update","title":"v2.0.0
: Major Update","text":"This is the first major update of mockery. Version 2 brings a handful of improvements to mockery:
- Structured and pretty console logging
- CLI now switches over to sp13/cobra
- Use of viper configuration parsing. You can now use a .mockery.yaml config file in your repository
- Various CI fixes and improvements
"},{"location":"configuration/","title":"Configuration","text":"mockery uses spf13/viper under the hood for its configuration parsing.
"},{"location":"configuration/#merging-precedence","title":"Merging Precedence","text":"The configuration applied to a specific mocked interface is merged according to the following precedence (in decreasing priority):
- Interface-specific config in
.mockery.yaml
- Package-specific config in
.mockery.yaml
- Command-line options
- Environment variables
- Top-level defaults in
.mockery.yaml
"},{"location":"configuration/#formatting","title":"Formatting","text":"If a parameter is named with-expecter
and we want a value of True
, then these are the formats for each source:
source value command line --with-expecter=true
Environment variable MOCKERY_WITH_EXPECTER=True
yaml with-expecter: True
"},{"location":"configuration/#recommended-basic-config","title":"Recommended Basic Config","text":"Copy the recommended basic configuration to a file called .mockery.yaml
at the top-level of your repo:
.mockery.yamlwith-expecter: true\npackages:\n github.com/your-org/your-go-project:\n # place your package-specific config here\n config:\n interfaces:\n # select the interfaces you want mocked\n Foo:\n # Modify package-level config for this specific interface (if applicable)\n config:\n
mockery will search upwards from your current-working-directory up to the root path, so the same configuration should be able to follow you within your project.
See the features
section for more details on how the config is structured.
"},{"location":"configuration/#parameter-descriptions","title":"Parameter Descriptions","text":"new style packages
config
The packages
config section is the new style of configuration. All old config semantics, including go:generate
and any config files lacking the packages
section is officially deprecated as of v2.31.0. Legacy semantics will be completely removed in v3.
Please see the features section for more details on how packages
works, including some example configuration.
Please see the migration docs for details on how to migrate your config.
name templated default description all
false
Generate all interfaces for the specified packages. boilerplate-file
\"\"
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. config
\"\"
Set the location of the mockery config file. dir
\"mocks/{{.PackagePath}}\"
The directory where the mock file will be outputted to. disable-config-search
false
Disable searching for configuration files disable-func-mocks
false
Disable generation of function mocks. disable-version-string
false
Disable the version string in the generated mock files. dry-run
false
Print the actions that would be taken, but don't perform the actions. exclude
[]
Specify subpackages to exclude when using recursive: True
exclude-regex
\"\"
When set along with include-regex
, then interfaces which match include-regex
but also match exclude-regex
will not be generated. If all
is set, or if include-regex
is not set, then exclude-regex
has no effect. filename
\"mock_{{.InterfaceName}}.go\"
The name of the file the mock will reside in. include-auto-generated
true
Set to false
if you need mockery to skip auto-generated files during its recursive package discovery. When set to true
, mockery includes auto-generated files when determining if a particular directory is an importable package. include-regex
\"\"
When set, only interface names that match the expression will be generated. This setting is ignored if all: True
is specified in the configuration. To further refine the interfaces generated, use exclude-regex
. inpackage
false
When generating mocks alongside the original interfaces, you must specify inpackage: True
to inform mockery that the mock is being placed in the same package as the original interface. log-level
\"info\"
Set the level of the logger mock-build-tags
\"\"
Set the build tags of the generated mocks. Read more about the format. mockname
\"Mock{{.InterfaceName}}\"
The name of the generated mock. outpkg
\"{{.PackageName}}\"
Use outpkg
to specify the package name of the generated mocks. packages
null
A dictionary containing configuration describing the packages and interfaces to generate mocks for. print
false
Use print: True
to have the resulting code printed out instead of written to disk. recursive
false
When set to true
on a particular package, mockery will recursively search for all sub-packages and inject those packages into the config map. replace-type
null
Replaces aliases, packages and/or types during generation. tags
\"\"
A space-separated list of additional build tags to load packages. with-expecter
true
Use with-expecter: True
to generate EXPECT()
methods for your mocks. This is the preferred way to set up your mocks."},{"location":"configuration/#layouts","title":"Layouts","text":"Using different configuration parameters, we can deploy our mocks on-disk in various ways. These are some common layouts:
layouts
defaultsadjacent to interface YAMLfilename: \"mock_{{.InterfaceName}}.go\"\ndir: \"mocks/{{.PackagePath}}\"\nmockname: \"Mock{{.InterfaceName}}\"\noutpkg: \"{{.PackageName}}\"\n
If these variables aren't specified, the above values will be applied to the config options. This strategy places your mocks into a separate mocks/
directory.
Interface Description
name value InterfaceName
MyDatabase
PackagePath
github.com/user/project/pkgName
PackageName
pkgName
Output
The mock will be generated at:
Text Onlymocks/github.com/user/project/pkgName/mock_MyDatabase.go\n
The mock file will look like:
Gopackage pkgName\n\nimport mock \"github.com/stretchr/testify/mock\"\n\ntype MockMyDatabase struct {\n mock.Mock\n}\n
Warning
Mockery does not protect against modifying original source code. Do not generate mocks using this config with uncommitted code changes.
YAMLfilename: \"mock_{{.InterfaceName}}.go\"\ndir: \"{{.InterfaceDir}}\"\nmockname: \"Mock{{.InterfaceName}}\"\noutpkg: \"{{.PackageName}}\"\ninpackage: True\n
Instead of the mocks being generated in a different folder, you may elect to generate the mocks alongside the original interface in your package. This may be the way most people define their configs, as it removes circular import issues that can happen with the default config.
For example, the mock might be generated along side the original source file like this:
Text Only./path/to/pkg/db.go\n./path/to/pkg/mock_MyDatabase.go\n
Interface Description
name value InterfaceName
MyDatabase
PackagePath
github.com/user/project/path/to/pkg
PackagePathRelative
path/to/pkg
PackageName
pkgName
SourceFile
./path/to/pkg/db.go
Output
Mock file will be generated at:
Text Only./path/to/pkg/mock_MyDatabase.go\n
The mock file will look like:
Gopackage pkgName\n\nimport mock \"github.com/stretchr/testify/mock\"\n\ntype MockMyDatabase struct {\n mock.Mock\n}\n
"},{"location":"configuration/#templated-strings","title":"Templated Strings","text":"mockery configuration makes use of the Go templating system.
"},{"location":"configuration/#variables","title":"Variables","text":"Note
Templated variables are only available when using the packages
config feature.
Variables that are marked as being templated are capable of using mockery-provided template parameters.
name description ConfigDir The directory path of the config file used. This is used to allow generation of mocks in a directory relative to the .mockery.yaml
file, e.g. external interfaces. InterfaceDir The directory path of the original interface being mocked. This can be used as dir: \"{{.InterfaceDir}}\"
to place your mocks adjacent to the original interface. This should not be used for external interfaces. InterfaceDirRelative The directory path of the original interface being mocked, relative to the current working directory. If the path cannot be made relative to the current working directory, this variable will be set equal to PackagePath
InterfaceFile The file path of the original interface being mocked. NOTE: This option will only write one mock implementation to the output file. If multiple mocks are defined in your original file, only one mock will be written to the output. InterfaceName The name of the original interface being mocked InterfaceNameCamel Converts a string interface_name
to InterfaceName
. DEPRECATED: use {{ .InterfaceName | camelcase }}
instead InterfaceNameLowerCamel Converts InterfaceName
to interfaceName
. DEPRECATED: use {{ .InterfaceName | camelcase | firstLower }}
instead InterfaceNameSnake Converts InterfaceName
to interface_name
. DEPRECATED: use {{ .InterfaceName | snakecase }}
instead InterfaceNameLower Converts InterfaceName
to interfacename
. DEPRECATED: use {{ .InterfaceName | lower }}
instead Mock A string that is Mock
if the interface is exported, or mock
if it is not exported. Useful when setting the name of your mock to something like: mockname: \"{{.Mock}}{{.InterfaceName}}\"
This way, the mock name will retain the exported-ness of the original interface. MockName The name of the mock that will be generated. Note that this is simply the mockname
configuration variable PackageName The name of the package from the original interface PackagePath The fully qualified package path of the original interface"},{"location":"configuration/#functions","title":"Functions","text":"Note
Templated functions are only available when using the packages
config feature.
Template functions allow you to inspect and manipulate template variables.
All template functions are calling native Go functions under the hood, so signatures and return values matches the Go functions you are probably already familiar with.
To learn more about the templating syntax, please see the Go text/template
documentation
contains
string substr hasPrefix
string prefix hasSuffix
string suffix join
elems sep replace
string old new n replaceAll
string old new split
string sep splitAfter
string sep splitAfterN
string sep n trim
string cutset trimLeft
string cutset trimPrefix
string prefix trimRight
string cutset trimSpace
string trimSuffix
string suffix lower
string upper
string camelcase
string snakecase
string kebabcase
string firstLower
string firstUpper
string matchString
pattern quoteMeta
string base
string clean
string dir
string expandEnv
string getenv
string
"},{"location":"configuration/#legacy-config-options","title":"Legacy config options","text":"legacy configuration options The legacy config options will be removed in v3 and are deprecated (but supported) in v2.
name description all
It's common for a big package to have a lot of interfaces, so mockery provides all
. This option will tell mockery to scan all files under the directory named by --dir
(\".\" by default) and generates mocks for any interfaces it finds. This option implies recursive: True
. boilerplate-file
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. case
mockery generates files using the casing of the original interface name. This can be modified by specifying case: underscore
to format the generated file name using underscore casing. exclude
This parameter is a list of strings representing path prefixes that should be excluded from mock generation. exported
Use exported: True
to generate public mocks for private interfaces. filename
Use the filename
and structname
to override the default generated file and struct name. These options are only compatible with non-regular expressions in name
, where only one mock is generated. inpackage-suffix
When inpackage-suffix
is set to True
, mock files are suffixed with _mock
instead of being prefixed with mock_
for InPackage mocks inpackage
and keeptree
For some complex repositories, there could be multiple interfaces with the same name but in different packages. In that case, inpackage
allows generating the mocked interfaces directly in the package that it mocks. In the case you don't want to generate the mocks into the package but want to keep a similar structure, use the option keeptree
. name
The name
option takes either the name or matching regular expression of the interface to generate mock(s) for. output
mockery always generates files with the package mocks
to keep things clean and simple. You can control which mocks directory is used by using output
, which defaults to ./mocks
. outpkg
Use outpkg
to specify the package name of the generated mocks. print
Use print: True
to have the resulting code printed out instead of written to disk. recursive
Use the recursive
option to search subdirectories for the interface(s). This option is only compatible with name
. The all
option implies recursive: True
. replace-type source=destination
Replaces aliases, packages and/or types during generation. testonly
Prepend every mock file with _test.go
. This is useful in cases where you are generating mocks inpackage
but don't want the mocks to be visible to code outside of tests. with-expecter
Use with-expecter: True
to generate EXPECT()
methods for your mocks. This is the prefervar(--md-code-hl-number-color) way to setup your mocks."},{"location":"deprecations/","title":"Deprecations","text":""},{"location":"deprecations/#packages","title":"packages
","text":"The packages
feature will be the only way to configure mockery in the future.
"},{"location":"deprecations/#issue-845-fix","title":"issue-845-fix
","text":"This parameter fixes a somewhat uninteresting, but important issue found in #845. In short, mockery ignored the outpkg:
parameter if inpackage:
was set to True
. This prevents users from being able to set alternate package names for their mocks that are generated in the same directory as the mocked interface. For example, it's legal Go to append _test
to the mock package name if the file is appended with _test.go
as well. This parameter will be permanently enabled in mockery v3.
As an example, if you had configuration that looked like this:
YAMLall: True\ndir: \"{{.InterfaceDir}}\"\nmockname: \"{{.InterfaceName}}Mock\"\noutpkg: \"{{.PackageName}}_test\"\nfilename: \"mock_{{.InterfaceName}}_test.go\"\ninpackage: True\n
The outpkg
parameter would not be respected and instead would be forced to take on the value of \"{{.PackageName}}\"
. To remove the warning, you must set:
YAMLissue-845-fix: True\n
After this is done, mocks generated in the old scheme will properly respect the outpkg:
parameter previously set if being generated with inpackage: True
.
"},{"location":"deprecations/#resolve-type-alias","title":"resolve-type-alias
","text":"This parameter directs Mockery on whether it should resolve a type alias to its underlying, real type or if it should generate mocks by referencing. Mockery was changed in #808 to support a new language feature that exposed type aliases in the parsed syntax tree. This meant that Mockery was now explicitly aware of aliases, which fixed a number of problems:
- #803
- #331
However, it was discovered in #839 that this was in fact a backwards-incompatible change. Thus, to maintain backwards compatability guarantees, we created this parameter that will be set to True
by default.
For all new projects that use Mockery, there is no reason to resolve type aliases so this parameter should almost always be set to False
. This will be the permanent behavior in Mockery v3.
"},{"location":"examples/","title":"Examples","text":"Tip
IDEs are really useful when interacting with mockery objects. All mockery objects embed the github.com/stretchr/testify/mock.Mock
object so you have access to both methods provided by mockery, and from testify itself. IDE auto-completion will show you all methods available for your use.
"},{"location":"examples/#simple-case","title":"Simple case","text":"Given this interface:
string.gopackage example_project\n\ntype Stringer interface {\n String() string\n}\n
Create a mock for this interface by specifying it in your config. We can then create a test using this new mock object:
string_test.gopackage example_project\n\nimport (\n \"testing\"\n\n \"github.com/stretchr/testify/assert\"\n)\n\nfunc Foo(s Stringer) string {\n return s.String()\n}\n\nfunc TestString(t *testing.T) {\n mockStringer := NewMockStringer(t)\n mockStringer.EXPECT().String().Return(\"mockery\")\n assert.Equal(t, \"mockery\", Foo(mockStringer))\n}\n
Note that in combination with using the mock's constructor and the .EXPECT()
directives, your test will automatically fail if the expected call is not made.
Alternate way of specifying expectations You can also use the github.com/stretchr/testify/mock.Mock
object directly (instead of using the .EXPECT()
methods, which provide type-safe-ish assertions).
string_test.gofunc TestString(t *testing.T) {\n mockStringer := NewMockStringer(t)\n mockStringer.On(\"String\").Return(\"mockery\")\n assert.Equal(t, \"mockery\", Foo(mockStringer))\n}\n
We recommend always interacting with the assertions through .EXPECT()
as mockery auto-generates methods that call out to Mock.On()
themselves, providing you with some amount of compile-time safety. Consider if all your expectations for String()
use the Mock.On()
methods, and you decide to add an argument to String()
to become String(foo string)
. Now, your existing tests will only fail when you run them. If you had used .EXPECT()
and regenerated your mocks after changing the function signature, your IDE, and the go compiler itself, would both tell you immediately that your expectations don't match the function signature.
"},{"location":"examples/#function-type-case","title":"Function type case","text":"Bug
Generating mocks for function types is likely not functioning in the packages
config semantics. You'll likely need to revert to the legacy semantics as shown below.
Given this is in send.go
Gopackage test\n\ntype SendFunc func(data string) (int, error)\n
Run: mockery --name=SendFunc
and the following will be output:
mock_SendFunc_test.gopackage mocks\n\nimport (\n \"github.com/stretchr/testify/mock\"\n\n testing \"testing\"\n)\n\ntype SendFunc struct {\n mock.Mock\n}\n\nfunc (_m *SendFunc) Execute(data string) (int, error) {\n ret := _m.Called(data)\n\n var r0 int\n if rf, ok := ret.Get(0).(func(string) int); ok {\n r0 = rf(data)\n } else {\n r0 = ret.Get(0).(int)\n }\n\n var r1 error\n if rf, ok := ret.Get(1).(func(string) error); ok {\n r1 = rf(data)\n } else {\n r1 = ret.Error(1)\n }\n\n return r0, r1\n}\n\n// NewSendFunc creates a new instance of SendFunc. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.\nfunc NewSendFunc(t testing.TB) *SendFunc {\n mock := &SendFunc{}\n mock.Mock.Test(t)\n\n t.Cleanup(func() { mock.AssertExpectations(t) })\n\n return mock\n}\n
"},{"location":"examples/#return-value-provider-functions","title":"Return Value Provider Functions","text":"If your tests need access to the arguments to calculate the return values, set the return value to a function that takes the method's arguments as its own arguments and returns the return value. For example, given this interface:
Gopackage test\n\ntype Proxy interface {\n passthrough(ctx context.Context, s string) string\n}\n
The argument can be passed through as the return value:
Goimport . \"github.com/stretchr/testify/mock\"\n\nproxyMock := mocks.NewProxy(t)\nproxyMock.On(\"passthrough\", mock.AnythingOfType(\"context.Context\"), mock.AnythingOfType(\"string\")).\n Return(func(ctx context.Context, s string) string {\n return s\n })\n
"},{"location":"features/","title":"Features","text":""},{"location":"features/#replace-types","title":"Replace Types","text":" v2.23.0
The replace-type
parameter allows adding a list of type replacements to be made in package and/or type names. This can help overcome issues like usage of type aliases that point to internal packages.
The format of the parameter is:
originalPackagePath.originalTypeName=newPackageName:newPackagePath.newTypeName
For example:
Bashmockery --replace-type github.com/vektra/mockery/v2/baz/internal/foo.InternalBaz=baz:github.com/vektra/mockery/v2/baz.Baz\n
This will replace any imported named \"github.com/vektra/mockery/v2/baz/internal/foo\"
with baz \"github.com/vektra/mockery/v2/baz\"
. The alias is defined with :
before the package name. Also, the InternalBaz
type that comes from this package will be renamed to baz.Baz
.
This next example fixes a common problem of type aliases that point to an internal package.
cloud.google.com/go/pubsub.Message
is a type alias defined like this:
Goimport (\n ipubsub \"cloud.google.com/go/internal/pubsub\"\n)\n\ntype Message = ipubsub.Message\n
The Go parser that mockery uses doesn't provide a way to detect this alias and sends the application the package and type name of the type in the internal package, which will not work.
We can use replace-type
with only the package part to replace any import of cloud.google.com/go/internal/pubsub
to cloud.google.com/go/pubsub
. We don't need to change the alias or type name in this case, because they are pubsub
and Message
in both cases.
Bashmockery --replace-type cloud.google.com/go/internal/pubsub=cloud.google.com/go/pubsub\n
Original source:
Goimport (\n \"cloud.google.com/go/pubsub\"\n)\n\ntype Handler struct {\n HandleMessage(m pubsub.Message) error\n}\n
Invalid mock generated without this parameter (points to an internal
folder):
Goimport (\n mock \"github.com/stretchr/testify/mock\"\n\n pubsub \"cloud.google.com/go/internal/pubsub\"\n)\n\nfunc (_m *Handler) HandleMessage(m pubsub.Message) error {\n // ...\n return nil\n}\n
Correct mock generated with this parameter.
Goimport (\n mock \"github.com/stretchr/testify/mock\"\n\n pubsub \"cloud.google.com/go/pubsub\"\n)\n\nfunc (_m *Handler) HandleMessage(m pubsub.Message) error {\n // ...\n return nil\n}\n
Generic type constraints can also be replaced by targeting the changed parameter with the square bracket notation on the left-hand side.
Bashmockery --replace-type github.com/vektra/mockery/v2/baz/internal/foo.InternalBaz[T]=github.com/vektra/mockery/v2/baz.Baz\n
For example:
Gotype InternalBaz[T any] struct{}\n\nfunc (*InternalBaz[T]) Foo() T {}\n\n// Becomes\ntype InternalBaz[T baz.Baz] struct{}\n\nfunc (*InternalBaz[T]) Foo() T {}\n
If a type constraint needs to be removed and replaced with a type, target the constraint with square brackets and include a '-' in front to have it removed.
Bashmockery --replace-type github.com/vektra/mockery/v2/baz/internal/foo.InternalBaz[-T]=github.com/vektra/mockery/v2/baz.Baz\n
For example:
Gotype InternalBaz[T any] struct{}\n\nfunc (*InternalBaz[T]) Foo() T {}\n\n// Becomes\ntype InternalBaz struct{}\n\nfunc (*InternalBaz) Foo() baz.Baz {}\n
When replacing a generic constraint, you can replace the type with a pointer by adding a '*' before the output type name.
Bashmockery --replace-type github.com/vektra/mockery/v2/baz/internal/foo.InternalBaz[-T]=github.com/vektra/mockery/v2/baz.*Baz\n
For example:
Gotype InternalBaz[T any] struct{}\n\nfunc (*InternalBaz[T]) Foo() T {}\n\n// Becomes\ntype InternalBaz struct{}\n\nfunc (*InternalBaz) Foo() *baz.Baz {}\n
"},{"location":"features/#packages-configuration","title":"packages
configuration","text":" v2.21.0
Info
See the Migration Docs on how to migrate to this new feature.
Mockery has a configuration parameter called packages
. In this config section, you define the packages and the interfaces you want mocks generated for. The packages can be any arbitrary package, either your own project or anything within the Go ecosystem. You may provide package-level or interface-level overrides to the default config you provide.
Usage of the packages
config section is desirable for multiple reasons:
- Up to 5x increase in mock generation speed over the legacy method
- Granular control over interface generation, location, and file names
- Singular location for all config, instead of spread around by
//go:generate
statements - Clean, easy to understand.
"},{"location":"features/#examples","title":"Examples","text":"Here is an example configuration set:
YAMLwith-expecter: True\npackages:\n github.com/vektra/mockery/v2/pkg: # (1)!\n interfaces:\n TypesPackage:\n RequesterVariadic:\n config: # (2)!\n with-expecter: False \n configs:\n - mockname: MockRequesterVariadicOneArgument\n unroll-variadic: False\n - mockname: MockRequesterVariadic\n io:\n config:\n all: True # (3)!\n interfaces:\n Writer:\n config:\n with-expecter: False # (4)!\n
- For this package, we provide no package-level config (which means we inherit the defaults at the top-level). Since our default of
all:
is False
, mockery will only generate the interfaces we specify. We tell it which interface to generate by using the interfaces
section and specifying an empty map, one for each interface. - There might be cases where you want multiple mocks generated from the same interface. To do this, you can define a default
config
section for the interface, and further configs
(plural) section, one for each mock. You must specify a mockname
for the mocks in this section to differentiate them. - This is telling mockery to generate all interfaces in the
io
package. - We can provide interface-specific overrides to the generation config.
"},{"location":"features/#templated-variables","title":"Templated variables","text":"Note
Templated variables are only available when using the packages
config feature.
Included with this feature is the ability to use templated strings for various configuration options. This is useful to define where your mocks are placed and how to name them. You can view the template variables available in the Configuration section of the docs.
"},{"location":"features/#recursive-package-discovery","title":"Recursive package discovery","text":" v2.25.0
When recursive: true
is set on a particular package:
YAMLpackages:\n github.com/user/project:\n config:\n recursive: true\n with-expecter: true\n
mockery will dynamically discover all sub-packages within the specified package. This is done by calling packages.Load
on the specified package, which induces Go to download the package from the internet (or simply your local project). Mockery then recursively discovers all sub-directories from the root package that also contain .go
files and injects the respective package path into the config map as if you had specified them manually. As an example, your in-memory config map may end up looking like this:
YAMLpackages:\n github.com/user/project:\n config:\n recursive: true\n with-expecter: true\n github.com/user/project/subpkg1:\n config:\n recursive: true\n with-expecter: true\n github.com/user/project/subpkg2:\n config:\n recursive: true\n with-expecter: true\n
You can use the showconfig
command to see the config mockery injects. The output of showconfig
theoretically could be copy-pasted into your YAML file as it is semantically equivalent.
mockery will not recurse into submodules, i.e. any subdirectory that contains a go.mod file. You must specify the submodule as a separate line item in the config if you would like mocks generated for it as well.
performance characteristics The performance when using recursive: true
may be worse than manually specifying all packages statically in the YAML file. This is because of the fact that mockery has to recursively walk the filesystem path that contains the package in question. It may unnecessarily walk down unrelated paths (for example, a Python virtual environment that is in the same path as your package). For this reason, it is recommended not to use recursive: true
if it can be avoided.
"},{"location":"features/#regex-matching","title":"Regex matching","text":"You can filter matched interfaces using the include-regex
option. To generate mocks only for interfaces ending in Client
we can use the following configuration:
YAMLpackages:\n github.com/user/project:\n config:\n recursive: true\n include-regex: \".*Client\"\n
To further refine matched interfaces, you can also use exclude-regex
. If an interface matches both include-regex
and exclude-regex
then it will not be generated. For example, to generate all interfaces except those ending in Func
:
YAMLpackages:\n github.com/user/project:\n config:\n recursive: true\n include-regex: \".*\"\n exclude-regex: \".*Func\"\n
You can only use exclude-regex
with include-regex
. If set by itself, exclude-regex
has no effect.
all: true Using all: true
will override include-regex
(and exclude-regex
) and issue a warning.
"},{"location":"features/#mock-constructors","title":"Mock Constructors","text":" 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{}\nfactory.Test(t) // so that mock does not panic when a method is unexpected\ndefer factory.AssertExpectations(t)\n
Instead, you may simply use the constructor: Go
factory := mocks.NewFactory(t)\n
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.
"},{"location":"features/#expecter-structs","title":"Expecter Structs","text":" v2.10.0 \u00b7 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 {\n Get(path string) (string, error)\n}\n
You can use the expecter interface as such: Go
requesterMock := mocks.NewRequester(t)\nrequesterMock.EXPECT().Get(\"some path\").Return(\"result\", nil)\n
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.
GorequesterMock.EXPECT().\n Get(mock.Anything).\n RunAndReturn(func(path string) (string, error) { \n fmt.Println(path, \"was called\")\n return (\"result for \" + path), nil\n })\n
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.
"},{"location":"features/#return-value-providers","title":"Return Value Providers","text":" 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:
Gotype Proxy interface {\npassthrough(ctx context.Context, s string) (string, error)\n}\n
First form:
GoproxyMock := mocks.NewProxy(t)\nproxyMock.On(\"passthrough\", mock.AnythingOfType(\"context.Context\"), mock.AnythingOfType(\"string\")).\nReturn(\n func(ctx context.Context, s string) (string, error) {\n return s, nil\n }\n)\n
Second form:
GoproxyMock := mocks.NewProxy(t)\nproxyMock.On(\"passthrough\", mock.AnythingOfType(\"context.Context\"), mock.AnythingOfType(\"string\")).\nReturn(\n func(ctx context.Context, s string) string {\n return s\n },\n func(ctx context.Context, s string) error {\n return nil\n },\n)\n
"},{"location":"installation/","title":"Getting Started","text":""},{"location":"installation/#installation","title":"Installation","text":""},{"location":"installation/#github-release-recommended","title":"GitHub Release recommended","text":"Visit the releases page to download one of the pre-built binaries for your platform.
"},{"location":"installation/#go-install","title":"go install","text":"Supported, but not recommended: see wiki page and related discussions.
Warning
Do not use @latest
as this will pull from the latest, potentially untagged, commit on master.
"},{"location":"installation/#docker","title":"Docker","text":"Use the Docker image
Text Onlydocker pull vektra/mockery\n
Generate all the mocks for your project:
Text Onlydocker run -v \"$PWD\":/src -w /src vektra/mockery --all\n
"},{"location":"installation/#homebrew","title":"Homebrew","text":"Install through brew
Text Onlybrew install mockery\nbrew upgrade mockery\n
"},{"location":"migrating_to_packages/","title":"Migrating To Packages","text":"The packages feature is a new configuration scheme that aims to simplify and improve a lot of legacy behavior. This will be the only way to generate mocks in v3. These docs outline general principles for migrating to the new scheme.
"},{"location":"migrating_to_packages/#background","title":"Background","text":"mockery was built during the pre-module era of Golang. Much of its codebase and configuration syntax was designed around file-based operations. This model became highly inefficient once Golang migrated to module-based packages. The old configuration semantics also proved limiting -- many users introduced and requested feature additions to mockery to support esoteric use-cases. This proved to be a huge maintenance burden that existed solely because the configuration model could not flexibly describe all the situations users wanted. The packages
semantics provides us a few highly desirable traits:
- Orders of magnitude performance increase, due to calling
packages.Load
once or twice for an entire project, versus once per file in the legacy semantics. - Hierarchical configuration model that allows interface-specific config to be inherited from package-level config, which is inherited from defaults.
- Single configuration file that describes the entirety of mockery's behavior, instead of spread out by
//go:generate
statements. - Extensive and flexible usage of a Golang string templating environment that allows users to dynamically specify parameter values.
"},{"location":"migrating_to_packages/#configuration-changes","title":"Configuration Changes","text":"The existence of the packages:
map in your configuration acts as a feature flag that enables the feature.
The configuration parameters used in packages
should be considered to have no relation to their meanings in the legacy scheme. It is recommended to wipe out all previous configuration and command-line parameters previously used.
The configuration docs show the parameters that are available for use in the packages
scheme. You should only use the parameters shown in this section. Mockery will not prevent you from using the legacy parameter set, but doing so will result in undefined behavior.
All of the parameters in the config section can be specified at the top level of the config file, which serves as the default values. The packages
config section defines package-specific config. See some examples here.
"},{"location":"migrating_to_packages/#examples","title":"Examples","text":""},{"location":"migrating_to_packages/#separate-mocks-directory","title":"Separate mocks/
directory","text":"Take for example a configuration where you are specifying all: true
at the top of your repo, and you're placing your mocks in a separate mocks/
directory, mirroring the directory structure of your original repo.
YAMLtestonly: False\nwith-expecter: True\nkeeptree: True\nall: True\n
The equivalent config for packages
looks like this:
YAMLwith-expecter: True\ndir: mocks/{{ replaceAll .InterfaceDirRelative \"internal\" \"internal_\" }} #(1)!\nmockname: \"{{.InterfaceName}}\"\noutpkg: \"{{.PackageName}}\"\nfilename: \"{{.InterfaceName}}.go\"\nall: True\npackages:\n github.com/org/repo:\n config:\n recursive: True\n
- The use of
replaceAll
is a trick that is done to ensure mocks created for internal
packages can be imported outside the mock directory. This retains the behavior of the legacy config.
While the example config provided here is more verbose, that is because we're specifying many non-default values in order to retain strict equivalence for this example. It's recommended to refer to the configuration parameters to see the defaults provided.
"},{"location":"migrating_to_packages/#adjacent-to-interface","title":"Adjacent to interface","text":"Another common pattern in the legacy config is to place mocks next to the file that defined the interface.
YAMLwith-expecter: True\ninpackage: True\nall: True\n
For example, the mock file would be laid out like:
Text Only./getter.go\n./mock_Getter.go\n
The equivalent config would look like:
YAMLwith-expecter: True\ninpackage: True\ndir: \"{{.InterfaceDir}}\"\nmockname: \"Mock{{.InterfaceName}}\"\noutpkg: \"{{.PackageName}}\"\nfilename: \"mock_{{.InterfaceName}}.go\"\nall: True\npackages:\n github.com/org/repo:\n config:\n recursive: True\n
"},{"location":"migrating_to_packages/#gogenerate-directives","title":"//go:generate
directives","text":"Previously, the recommended way of generating mocks was to call mockery
once per interface using //go:generate
. Generating interface-specific mocks this way is no longer supported. You may still use //go:generate
to call mockery, however it will generate all interfaces defined in your config file. There currently exists no semantics to specify the generation of specific interfaces from the command line (not because we reject the idea, but because it was not seen as a requirement for the initial iteration of packages
).
"},{"location":"migrating_to_packages/#behavior-changes","title":"Behavior Changes","text":"The legacy behavior iterated over every .go
file in your project, called packages.Load
to parse the syntax tree, and generated mocks for every interface found in the file. The new behavior instead simply grabs the list of packages to load from the config file, or in the case of recursive: True
, walks the file-system tree to discover the packages that exist (without actually parsing the files). Using this list, it calls packages.Load
once with the list of packages that were discovered.
"},{"location":"migrating_to_packages/#filesystem-tree-layouts","title":"Filesystem Tree Layouts","text":"The legacy config provided the inpackage
parameter which, if inpackage: True
, would place the mocks in the same package as your interfaces. Otherwise, it would place it in a separate directory.
These two layouts are supported in the packages
scheme. See the relevant docs here.
"},{"location":"notes/","title":"Frequently Asked Questions","text":""},{"location":"notes/#error-no-go-files-found-in-root-search-path","title":"error: no go files found in root search path
","text":"When using the packages
feature, recursive: true
and you have specified a package that contains no *.go
files, mockery is unable to determine the on-disk location of the package in order to continue the recursive package search. This appears to be a limitation of the golang.org/x/tools/go/packages package that is used to parse package metadata.
The solution is to create a .go
file in the package's path and add a package [name]
directive at the top. It doesn't matter what the file is called. This allows mockery to properly read package metadata.
Discussion
"},{"location":"notes/#internal-error-package-without-types-was-imported","title":"internal error: package without types was imported","text":"https://github.com/vektra/mockery/issues/475
This issue indicates that you have attempted to use package in your dependency tree (whether direct or indirect) that uses Go language semantics that your currently-running Go version does not support. The solution:
- Update to the latest go version
- Delete all cached packages with
go clean -modcache
- Reinstall mockery
Additionally, this issue only happens when compiling mockery from source, such as with go install
. Our docs recommend not to use go install
as the success of your build depends on the compatibility of your Go version with the semantics in use. You would not encounter this issue if using one of the installation methods that install pre-built binaries, like downloading the .tar.gz
binaries, or through brew install
.
"},{"location":"notes/#multiple-expectations-with-identical-arguments","title":"Multiple Expectations With Identical Arguments","text":"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\ngetter := NewGetter()\nassert(t, \"foo\", getter.Get(\"key\"))\n\n// Return \"bar\" on the second call\nassert(t, \"bar\", getter.Get(\"key\"))\n
This can be done by using the .Once()
method on the mock call expectation:
GomockGetter := NewMockGetter(t)\nmockGetter.EXPECT().Get(mock.anything).Return(\"foo\").Once()\nmockGetter.EXPECT().Get(mock.anything).Return(\"bar\").Once()\n
Or you can identify an arbitrary number of times each value should be returned:
GomockGetter := NewMockGetter(t)\nmockGetter.EXPECT().Get(mock.anything).Return(\"foo\").Times(4)\nmockGetter.EXPECT().Get(mock.anything).Return(\"bar\").Times(2)\n
Note that with proper Go support in your IDE, all the available methods are self-documented in autocompletion help contexts.
"},{"location":"notes/#variadic-arguments","title":"Variadic Arguments","text":"Consider if we have a function func Bar(message ...string) error
. A typical assertion might look like this:
Gofunc TestFoo(t *testing.T) {\n m := NewMockFoo(t)\n m.On(\"Bar\", \"hello\", \"world\").Return(nil)\n
We might also want to make an assertion that says \"any number of variadic arguments\":
Gom.On(\"Bar\", mock.Anything).Return(nil)\n
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:
Gom.On(\"Bar\", mock.Anything).Return(nil)\n
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:
Gom.On(\"Bar\", mock.Anything).Return(nil)\n
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\nm.On(\"Bar\", mock.Anything).Return(nil)\n// case 2\nm.On(\"Bar\", []interface{}{mock.Anything}).Return(nil)\n
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
"},{"location":"notes/#semantic-versioning","title":"Semantic Versioning","text":"The versioning in this project applies only to the behavior of the mockery binary itself. This project explicitly does not promise a stable internal API, but rather a stable executable. The versioning applies to the following:
- CLI arguments.
- Parsing of Go code. New features in the Go language will be supported in a backwards-compatible manner, except during major version bumps.
- Behavior of mock objects. Mock objects can be considered to be part of the public API.
- Behavior of mockery given a set of arguments.
What the version does not track:
- The interfaces, objects, methods etc. in the vektra/mockery package.
- Compatibility of
go get
-ing mockery with new or old versions of Go.
"},{"location":"notes/#mocking-interfaces-in-main","title":"Mocking interfaces in main
","text":"When your interfaces are in the main package, you should supply the --inpackage
flag. This will generate mocks in the same package as the target code, avoiding import issues.
"},{"location":"notes/#mockery-fails-to-run-when-mockery_version-environment-variable-is-set","title":"mockery fails to run when MOCKERY_VERSION
environment variable is set","text":"This issue was first highlighted in this GitHub issue.
mockery uses the viper package for configuration mapping and parsing. Viper is set to automatically search for all config variables specified in its config struct. One of the config variables is named version
, which gets mapped to an environment variable called MOCKERY_VERSION
. If you set this environment variable, mockery attempts to parse it into the version
bool config.
This is an adverse effect of how our config parsing is set up. The solution is to rename your environment variable to something other than MOCKERY_VERSION
.
"},{"location":"running/","title":"Running","text":"If your .mockery.yaml
file has been populated with the packages and interfaces you want mocked, mockery can be run with no arguments. Take for example how the mockery project itself is configured:
YAMLquiet: False\nkeeptree: True\ndisable-version-string: True\nwith-expecter: True\nmockname: \"{{.InterfaceName}}\"\nfilename: \"{{.MockName}}.go\"\noutpkg: mocks\npackages:\n github.com/vektra/mockery/v2/pkg:\n interfaces:\n TypesPackage:\n# Lots more config...\n
From anywhere within your repo, you can simply call mockery
once, and it will find your config either by respecting the config
path you gave it, or by searching upwards from the current working directory.
Bashmockery\n08 Jul 23 01:40 EDT INF Starting mockery dry-run=false version=v2.31.0\n08 Jul 23 01:40 EDT INF Using config: /Users/landonclipp/git/LandonTClipp/mockery/.mockery.yaml dry-run=false version=v2.31.0\n
Command line arguments
It is valid to specify arguments from the command line. The configuration precedence is specified in the Configuration docs.
"}]}
\ No newline at end of file
+{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"mockery","text":"Mockery is a project that creates mock implementations of Golang interfaces. The mocks generated in this project are based off of the github.com/stretchr/testify suite of testing packages.
"},{"location":"#why-mockery","title":"Why mockery?","text":"When you have an interface like this:
db.gotype DB interface {\n Get(val string) string\n}\n
and a function that takes this interface:
db_getter.gofunc getFromDB(db DB) string {\n return db.Get(\"ice cream\")\n}\n
You can test getFromDB
by either instantiating a testing database, or you can simply create a mock implementation of DB
using mockery. Mockery can automatically generate a mock implementation that allows us to define assertions on how the mock was used, what to return, and other useful tidbits. We can add a //go:generate
directive above our interface:
db.go//go:generate mockery --name DB\ntype DB interface {\n Get(val string) string\n}\n
.mockery.yamlinpackage: True # (1)!\nwith-expecter: True # (2)!\ntestonly: True # (3)!\n
- Generate our mocks next to the original interface
- Create expecter methods
- Append
_test.go
to the filename so the mock object is not packaged
Bash$ go generate \n05 Mar 23 21:49 CST INF Starting mockery dry-run=false version=v2.20.0\n05 Mar 23 21:49 CST INF Using config: .mockery.yaml dry-run=false version=v2.20.0\n05 Mar 23 21:49 CST INF Walking dry-run=false version=v2.20.0\n05 Mar 23 21:49 CST INF Generating mock dry-run=false interface=DB qualified-name=github.com/vektra/mockery/v2/pkg/fixtures/example_project version=v2.20.0\n
We can then use the mock object in a test:
db_getter_test.goimport (\n \"testing\"\n\n \"github.com/stretchr/testify/assert\"\n)\n\nfunc Test_getFromDB(t *testing.T) {\n mockDB := NewMockDB(t)\n mockDB.EXPECT().Get(\"ice cream\").Return(\"chocolate\").Once()\n flavor := getFromDB(mockDB)\n assert.Equal(t, \"chocolate\", flavor)\n}\n
"},{"location":"#why-use-mockery-over-gomock","title":"Why use mockery over gomock?","text":" - mockery provides a much more user-friendly API and is less confusing to use
- mockery utilizes
testify
which is a robust and highly feature-rich testing framework - mockery has rich configuration options that allow fine-grained control over how your mocks are generated
- mockery's CLI is more robust, user-friendly, and provides many more options
- mockery supports generics (this may no longer be an advantage if/when gomock supports generics)
"},{"location":"#who-uses-mockery","title":"Who uses mockery?","text":" - Grafana
- Google Skia
- Google Skyzkaller
- Hashicorp
- Uber Cadence
- Jaegertracing
- Splunk kafka-mq-go
-
-
-
- eksctl
-
- Task
-
Get Started
"},{"location":"changelog/","title":"Changelog","text":"This changelog describes major feature additions. Please view the releases
page for more details on commits and minor changes.
"},{"location":"changelog/#v2290-template-functions","title":"v2.29.0
template functions","text":"This release adds a large number of template functions available for use in the packages
templating engine.
"},{"location":"changelog/#v2250-recursive-config","title":"v2.25.0
recursive
config","text":"The recursive
parameter allows mockery to dynamically discover sub-packages when using the packages
config.
"},{"location":"changelog/#v2240-exclude-config","title":"v2.24.0
exclude
config","text":"The exclude
parameter allows you to define subpaths to ignore. This is currently only compatible when using non-packages
config.
"},{"location":"changelog/#v2230-replace-types","title":"v2.23.0
Replace Types","text":"The replace-type
parameter allows adding a list of type replacements to be made in package and/or type names. This can help overcome issues like usage of type aliases that point to internal packages.
"},{"location":"changelog/#v2210-packages-configuration","title":"v2.21.0
: packages
configuration","text":"In this version we release the packages
configuration section. This new parameter allows defining specific packages to generate mocks for, while also giving fine-grained control over which interfaces are mocked, where they are located, and how they are configured. Details are provided here.
Community input is desired before we consider deprecations of dynamic walking (via all: True
): https://github.com/vektra/mockery/discussions/549
"},{"location":"changelog/#v2200-improved-return-value-functions","title":"v2.20.0
: Improved Return Value Functions","text":"Return value functions that return an entire method's return value signature can now be provided.
GoproxyMock := mocks.NewProxy(t)\nproxyMock.On(\"passthrough\", mock.AnythingOfType(\"context.Context\"), mock.AnythingOfType(\"string\")).\nReturn(\n func(ctx context.Context, s string) (string, error) {\n return s, nil\n }\n)\n
You may still use the old way where one function is provided for each return value:
GoproxyMock := mocks.NewProxy(t)\nproxyMock.On(\"passthrough\", mock.AnythingOfType(\"context.Context\"), mock.AnythingOfType(\"string\")).\nReturn(\n func(ctx context.Context, s string) string {\n return s\n },\n func(ctx context.Context, s string) error {\n return nil\n },\n)\n
"},{"location":"changelog/#2190-inpackage-suffix-option","title":"2.19.0
: inpackage-suffix
option","text":"When inpackage-suffix
is set to True
, mock files are suffixed with _mock
instead of being prefixed with mock_
for InPackage mocks
"},{"location":"changelog/#v2160-config-search-path","title":"v2.16.0
: Config Search Path","text":"Mockery will iteratively search every directory from the current working directory up to the root path for a .mockery.yaml
file, if one is not explicitly provided.
"},{"location":"changelog/#v2130-generics-support","title":"v2.13.0
: Generics support","text":"Mocks are now capable of supporting Golang generics.
"},{"location":"changelog/#v2110-mock-constructors","title":"v2.11.0
: Mock constructors","text":"Mockery v2.11 introduces constructors for all mocks. This makes instantiation and mock registration a bit easier and less error-prone (you won't have to worry about forgetting the AssertExpectations
method call anymore).
Before v2.11: Go
factory := &mocks.Factory{}\nfactory.Test(t) // so that mock does not panic when a method is unexpected\ndefer factory.AssertExpectations(t)\n
After v2.11: Go
factory := mocks.NewFactory(t)\n
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.
"},{"location":"changelog/#v2100-expecter-structs","title":"v2.10.0
: Expecter Structs","text":"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 {\n Get(path string) (string, error)\n}\n
You can use the type-safe expecter interface as such: Go
requesterMock := mocks.NewRequester(t)\nrequesterMock.EXPECT().Get(\"some path\").Return(\"result\", nil)\nrequesterMock.EXPECT().\n Get(mock.Anything).\n Run(func(path string) { fmt.Println(path, \"was called\") }).\n // Can still use return functions by getting the embedded mock.Call\n Call.Return(func(path string) string { return \"result for \" + path }, nil)\n
"},{"location":"changelog/#v200-major-update","title":"v2.0.0
: Major Update","text":"This is the first major update of mockery. Version 2 brings a handful of improvements to mockery:
- Structured and pretty console logging
- CLI now switches over to sp13/cobra
- Use of viper configuration parsing. You can now use a .mockery.yaml config file in your repository
- Various CI fixes and improvements
"},{"location":"configuration/","title":"Configuration","text":"mockery uses spf13/viper under the hood for its configuration parsing.
"},{"location":"configuration/#merging-precedence","title":"Merging Precedence","text":"The configuration applied to a specific mocked interface is merged according to the following precedence (in decreasing priority):
- Interface-specific config in
.mockery.yaml
- Package-specific config in
.mockery.yaml
- Command-line options
- Environment variables
- Top-level defaults in
.mockery.yaml
"},{"location":"configuration/#formatting","title":"Formatting","text":"If a parameter is named with-expecter
and we want a value of True
, then these are the formats for each source:
source value command line --with-expecter=true
Environment variable MOCKERY_WITH_EXPECTER=True
yaml with-expecter: True
"},{"location":"configuration/#recommended-basic-config","title":"Recommended Basic Config","text":"Copy the recommended basic configuration to a file called .mockery.yaml
at the top-level of your repo:
.mockery.yamlwith-expecter: true\npackages:\n github.com/your-org/your-go-project:\n # place your package-specific config here\n config:\n interfaces:\n # select the interfaces you want mocked\n Foo:\n # Modify package-level config for this specific interface (if applicable)\n config:\n
mockery will search upwards from your current-working-directory up to the root path, so the same configuration should be able to follow you within your project.
See the features
section for more details on how the config is structured.
"},{"location":"configuration/#parameter-descriptions","title":"Parameter Descriptions","text":"new style packages
config
The packages
config section is the new style of configuration. All old config semantics, including go:generate
and any config files lacking the packages
section is officially deprecated as of v2.31.0. Legacy semantics will be completely removed in v3.
Please see the features section for more details on how packages
works, including some example configuration.
Please see the migration docs for details on how to migrate your config.
name templated default description all
false
Generate all interfaces for the specified packages. boilerplate-file
\"\"
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. config
\"\"
Set the location of the mockery config file. dir
\"mocks/{{.PackagePath}}\"
The directory where the mock file will be outputted to. disable-config-search
false
Disable searching for configuration files disable-func-mocks
false
Disable generation of function mocks. disable-version-string
false
Disable the version string in the generated mock files. dry-run
false
Print the actions that would be taken, but don't perform the actions. exclude
[]
Specify subpackages to exclude when using recursive: True
exclude-regex
\"\"
When set along with include-regex
, then interfaces which match include-regex
but also match exclude-regex
will not be generated. If all
is set, or if include-regex
is not set, then exclude-regex
has no effect. filename
\"mock_{{.InterfaceName}}.go\"
The name of the file the mock will reside in. include-auto-generated
true
Set to false
if you need mockery to skip auto-generated files during its recursive package discovery. When set to true
, mockery includes auto-generated files when determining if a particular directory is an importable package. include-regex
\"\"
When set, only interface names that match the expression will be generated. This setting is ignored if all: True
is specified in the configuration. To further refine the interfaces generated, use exclude-regex
. inpackage
false
When generating mocks alongside the original interfaces, you must specify inpackage: True
to inform mockery that the mock is being placed in the same package as the original interface. log-level
\"info\"
Set the level of the logger mock-build-tags
\"\"
Set the build tags of the generated mocks. Read more about the format. mockname
\"Mock{{.InterfaceName}}\"
The name of the generated mock. outpkg
\"{{.PackageName}}\"
Use outpkg
to specify the package name of the generated mocks. packages
null
A dictionary containing configuration describing the packages and interfaces to generate mocks for. print
false
Use print: True
to have the resulting code printed out instead of written to disk. recursive
false
When set to true
on a particular package, mockery will recursively search for all sub-packages and inject those packages into the config map. replace-type
null
Replaces aliases, packages and/or types during generation. tags
\"\"
A space-separated list of additional build tags to load packages. with-expecter
true
Use with-expecter: True
to generate EXPECT()
methods for your mocks. This is the preferred way to set up your mocks."},{"location":"configuration/#layouts","title":"Layouts","text":"Using different configuration parameters, we can deploy our mocks on-disk in various ways. These are some common layouts:
layouts
defaultsadjacent to interface YAMLfilename: \"mock_{{.InterfaceName}}.go\"\ndir: \"mocks/{{.PackagePath}}\"\nmockname: \"Mock{{.InterfaceName}}\"\noutpkg: \"{{.PackageName}}\"\n
If these variables aren't specified, the above values will be applied to the config options. This strategy places your mocks into a separate mocks/
directory.
Interface Description
name value InterfaceName
MyDatabase
PackagePath
github.com/user/project/pkgName
PackageName
pkgName
Output
The mock will be generated at:
Text Onlymocks/github.com/user/project/pkgName/mock_MyDatabase.go\n
The mock file will look like:
Gopackage pkgName\n\nimport mock \"github.com/stretchr/testify/mock\"\n\ntype MockMyDatabase struct {\n mock.Mock\n}\n
Warning
Mockery does not protect against modifying original source code. Do not generate mocks using this config with uncommitted code changes.
YAMLfilename: \"mock_{{.InterfaceName}}.go\"\ndir: \"{{.InterfaceDir}}\"\nmockname: \"Mock{{.InterfaceName}}\"\noutpkg: \"{{.PackageName}}\"\ninpackage: True\n
Instead of the mocks being generated in a different folder, you may elect to generate the mocks alongside the original interface in your package. This may be the way most people define their configs, as it removes circular import issues that can happen with the default config.
For example, the mock might be generated along side the original source file like this:
Text Only./path/to/pkg/db.go\n./path/to/pkg/mock_MyDatabase.go\n
Interface Description
name value InterfaceName
MyDatabase
PackagePath
github.com/user/project/path/to/pkg
PackagePathRelative
path/to/pkg
PackageName
pkgName
SourceFile
./path/to/pkg/db.go
Output
Mock file will be generated at:
Text Only./path/to/pkg/mock_MyDatabase.go\n
The mock file will look like:
Gopackage pkgName\n\nimport mock \"github.com/stretchr/testify/mock\"\n\ntype MockMyDatabase struct {\n mock.Mock\n}\n
"},{"location":"configuration/#templated-strings","title":"Templated Strings","text":"mockery configuration makes use of the Go templating system.
"},{"location":"configuration/#variables","title":"Variables","text":"Note
Templated variables are only available when using the packages
config feature.
Variables that are marked as being templated are capable of using mockery-provided template parameters.
name description ConfigDir The directory path of the config file used. This is used to allow generation of mocks in a directory relative to the .mockery.yaml
file, e.g. external interfaces. InterfaceDir The directory path of the original interface being mocked. This can be used as dir: \"{{.InterfaceDir}}\"
to place your mocks adjacent to the original interface. This should not be used for external interfaces. InterfaceDirRelative The directory path of the original interface being mocked, relative to the current working directory. If the path cannot be made relative to the current working directory, this variable will be set equal to PackagePath
InterfaceFile The file path of the original interface being mocked. NOTE: This option will only write one mock implementation to the output file. If multiple mocks are defined in your original file, only one mock will be written to the output. InterfaceName The name of the original interface being mocked InterfaceNameCamel Converts a string interface_name
to InterfaceName
. DEPRECATED: use {{ .InterfaceName | camelcase }}
instead InterfaceNameLowerCamel Converts InterfaceName
to interfaceName
. DEPRECATED: use {{ .InterfaceName | camelcase | firstLower }}
instead InterfaceNameSnake Converts InterfaceName
to interface_name
. DEPRECATED: use {{ .InterfaceName | snakecase }}
instead InterfaceNameLower Converts InterfaceName
to interfacename
. DEPRECATED: use {{ .InterfaceName | lower }}
instead Mock A string that is Mock
if the interface is exported, or mock
if it is not exported. Useful when setting the name of your mock to something like: mockname: \"{{.Mock}}{{.InterfaceName}}\"
This way, the mock name will retain the exported-ness of the original interface. MockName The name of the mock that will be generated. Note that this is simply the mockname
configuration variable PackageName The name of the package from the original interface PackagePath The fully qualified package path of the original interface"},{"location":"configuration/#functions","title":"Functions","text":"Note
Templated functions are only available when using the packages
config feature.
Template functions allow you to inspect and manipulate template variables.
All template functions are calling native Go functions under the hood, so signatures and return values matches the Go functions you are probably already familiar with.
To learn more about the templating syntax, please see the Go text/template
documentation
contains
string substr hasPrefix
string prefix hasSuffix
string suffix join
elems sep replace
string old new n replaceAll
string old new split
string sep splitAfter
string sep splitAfterN
string sep n trim
string cutset trimLeft
string cutset trimPrefix
string prefix trimRight
string cutset trimSpace
string trimSuffix
string suffix lower
string upper
string camelcase
string snakecase
string kebabcase
string firstLower
string firstUpper
string matchString
pattern quoteMeta
string base
string clean
string dir
string expandEnv
string getenv
string
"},{"location":"configuration/#legacy-config-options","title":"Legacy config options","text":"legacy configuration options The legacy config options will be removed in v3 and are deprecated (but supported) in v2.
name description all
It's common for a big package to have a lot of interfaces, so mockery provides all
. This option will tell mockery to scan all files under the directory named by --dir
(\".\" by default) and generates mocks for any interfaces it finds. This option implies recursive: True
. boilerplate-file
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. case
mockery generates files using the casing of the original interface name. This can be modified by specifying case: underscore
to format the generated file name using underscore casing. exclude
This parameter is a list of strings representing path prefixes that should be excluded from mock generation. exported
Use exported: True
to generate public mocks for private interfaces. filename
Use the filename
and structname
to override the default generated file and struct name. These options are only compatible with non-regular expressions in name
, where only one mock is generated. inpackage-suffix
When inpackage-suffix
is set to True
, mock files are suffixed with _mock
instead of being prefixed with mock_
for InPackage mocks inpackage
and keeptree
For some complex repositories, there could be multiple interfaces with the same name but in different packages. In that case, inpackage
allows generating the mocked interfaces directly in the package that it mocks. In the case you don't want to generate the mocks into the package but want to keep a similar structure, use the option keeptree
. name
The name
option takes either the name or matching regular expression of the interface to generate mock(s) for. output
mockery always generates files with the package mocks
to keep things clean and simple. You can control which mocks directory is used by using output
, which defaults to ./mocks
. outpkg
Use outpkg
to specify the package name of the generated mocks. print
Use print: True
to have the resulting code printed out instead of written to disk. recursive
Use the recursive
option to search subdirectories for the interface(s). This option is only compatible with name
. The all
option implies recursive: True
. replace-type source=destination
Replaces aliases, packages and/or types during generation. testonly
Prepend every mock file with _test.go
. This is useful in cases where you are generating mocks inpackage
but don't want the mocks to be visible to code outside of tests. with-expecter
Use with-expecter: True
to generate EXPECT()
methods for your mocks. This is the prefervar(--md-code-hl-number-color) way to setup your mocks."},{"location":"deprecations/","title":"Deprecations","text":""},{"location":"deprecations/#packages","title":"packages
","text":"To resolve this warning, use the packages
feature:
.mockery.yamlpackages:\n [...]\n
The packages
feature will be the only way to configure mockery in the future.
"},{"location":"deprecations/#issue-845-fix","title":"issue-845-fix
","text":"To resolve this warning:
.mockery.yamlissue-845-fix: True\n
This parameter fixes a somewhat uninteresting, but important issue found in #845. In short, mockery ignored the outpkg:
parameter if inpackage:
was set to True
. This prevents users from being able to set alternate package names for their mocks that are generated in the same directory as the mocked interface. For example, it's legal Go to append _test
to the mock package name if the file is appended with _test.go
as well. This parameter will be permanently enabled in mockery v3.
As an example, if you had configuration that looked like this:
YAMLall: True\ndir: \"{{.InterfaceDir}}\"\nmockname: \"{{.InterfaceName}}Mock\"\noutpkg: \"{{.PackageName}}_test\"\nfilename: \"mock_{{.InterfaceName}}_test.go\"\ninpackage: True\n
The outpkg
parameter would not be respected and instead would be forced to take on the value of \"{{.PackageName}}\"
. To remove the warning, you must set:
YAMLissue-845-fix: True\n
After this is done, mocks generated in the old scheme will properly respect the outpkg:
parameter previously set if being generated with inpackage: True
.
"},{"location":"deprecations/#resolve-type-alias","title":"resolve-type-alias
","text":"To resolve this warning:
.mockery.yamlresolve-type-alias: False\n
This parameter directs Mockery on whether it should resolve a type alias to its underlying, real type or if it should generate mocks by referencing. Mockery was changed in #808 to support a new language feature that exposed type aliases in the parsed syntax tree. This meant that Mockery was now explicitly aware of aliases, which fixed a number of problems:
- #803
- #331
However, it was discovered in #839 that this was in fact a backwards-incompatible change. Thus, to maintain backwards compatability guarantees, we created this parameter that will be set to True
by default.
For all new projects that use Mockery, there is no reason to resolve type aliases so this parameter should almost always be set to False
. This will be the permanent behavior in Mockery v3.
"},{"location":"examples/","title":"Examples","text":"Tip
IDEs are really useful when interacting with mockery objects. All mockery objects embed the github.com/stretchr/testify/mock.Mock
object so you have access to both methods provided by mockery, and from testify itself. IDE auto-completion will show you all methods available for your use.
"},{"location":"examples/#simple-case","title":"Simple case","text":"Given this interface:
string.gopackage example_project\n\ntype Stringer interface {\n String() string\n}\n
Create a mock for this interface by specifying it in your config. We can then create a test using this new mock object:
string_test.gopackage example_project\n\nimport (\n \"testing\"\n\n \"github.com/stretchr/testify/assert\"\n)\n\nfunc Foo(s Stringer) string {\n return s.String()\n}\n\nfunc TestString(t *testing.T) {\n mockStringer := NewMockStringer(t)\n mockStringer.EXPECT().String().Return(\"mockery\")\n assert.Equal(t, \"mockery\", Foo(mockStringer))\n}\n
Note that in combination with using the mock's constructor and the .EXPECT()
directives, your test will automatically fail if the expected call is not made.
Alternate way of specifying expectations You can also use the github.com/stretchr/testify/mock.Mock
object directly (instead of using the .EXPECT()
methods, which provide type-safe-ish assertions).
string_test.gofunc TestString(t *testing.T) {\n mockStringer := NewMockStringer(t)\n mockStringer.On(\"String\").Return(\"mockery\")\n assert.Equal(t, \"mockery\", Foo(mockStringer))\n}\n
We recommend always interacting with the assertions through .EXPECT()
as mockery auto-generates methods that call out to Mock.On()
themselves, providing you with some amount of compile-time safety. Consider if all your expectations for String()
use the Mock.On()
methods, and you decide to add an argument to String()
to become String(foo string)
. Now, your existing tests will only fail when you run them. If you had used .EXPECT()
and regenerated your mocks after changing the function signature, your IDE, and the go compiler itself, would both tell you immediately that your expectations don't match the function signature.
"},{"location":"examples/#function-type-case","title":"Function type case","text":"Bug
Generating mocks for function types is likely not functioning in the packages
config semantics. You'll likely need to revert to the legacy semantics as shown below.
Given this is in send.go
Gopackage test\n\ntype SendFunc func(data string) (int, error)\n
Run: mockery --name=SendFunc
and the following will be output:
mock_SendFunc_test.gopackage mocks\n\nimport (\n \"github.com/stretchr/testify/mock\"\n\n testing \"testing\"\n)\n\ntype SendFunc struct {\n mock.Mock\n}\n\nfunc (_m *SendFunc) Execute(data string) (int, error) {\n ret := _m.Called(data)\n\n var r0 int\n if rf, ok := ret.Get(0).(func(string) int); ok {\n r0 = rf(data)\n } else {\n r0 = ret.Get(0).(int)\n }\n\n var r1 error\n if rf, ok := ret.Get(1).(func(string) error); ok {\n r1 = rf(data)\n } else {\n r1 = ret.Error(1)\n }\n\n return r0, r1\n}\n\n// NewSendFunc creates a new instance of SendFunc. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.\nfunc NewSendFunc(t testing.TB) *SendFunc {\n mock := &SendFunc{}\n mock.Mock.Test(t)\n\n t.Cleanup(func() { mock.AssertExpectations(t) })\n\n return mock\n}\n
"},{"location":"examples/#return-value-provider-functions","title":"Return Value Provider Functions","text":"If your tests need access to the arguments to calculate the return values, set the return value to a function that takes the method's arguments as its own arguments and returns the return value. For example, given this interface:
Gopackage test\n\ntype Proxy interface {\n passthrough(ctx context.Context, s string) string\n}\n
The argument can be passed through as the return value:
Goimport . \"github.com/stretchr/testify/mock\"\n\nproxyMock := mocks.NewProxy(t)\nproxyMock.On(\"passthrough\", mock.AnythingOfType(\"context.Context\"), mock.AnythingOfType(\"string\")).\n Return(func(ctx context.Context, s string) string {\n return s\n })\n
"},{"location":"features/","title":"Features","text":""},{"location":"features/#replace-types","title":"Replace Types","text":" v2.23.0
The replace-type
parameter allows adding a list of type replacements to be made in package and/or type names. This can help overcome issues like usage of type aliases that point to internal packages.
The format of the parameter is:
originalPackagePath.originalTypeName=newPackageName:newPackagePath.newTypeName
For example:
Bashmockery --replace-type github.com/vektra/mockery/v2/baz/internal/foo.InternalBaz=baz:github.com/vektra/mockery/v2/baz.Baz\n
This will replace any imported named \"github.com/vektra/mockery/v2/baz/internal/foo\"
with baz \"github.com/vektra/mockery/v2/baz\"
. The alias is defined with :
before the package name. Also, the InternalBaz
type that comes from this package will be renamed to baz.Baz
.
This next example fixes a common problem of type aliases that point to an internal package.
cloud.google.com/go/pubsub.Message
is a type alias defined like this:
Goimport (\n ipubsub \"cloud.google.com/go/internal/pubsub\"\n)\n\ntype Message = ipubsub.Message\n
The Go parser that mockery uses doesn't provide a way to detect this alias and sends the application the package and type name of the type in the internal package, which will not work.
We can use replace-type
with only the package part to replace any import of cloud.google.com/go/internal/pubsub
to cloud.google.com/go/pubsub
. We don't need to change the alias or type name in this case, because they are pubsub
and Message
in both cases.
Bashmockery --replace-type cloud.google.com/go/internal/pubsub=cloud.google.com/go/pubsub\n
Original source:
Goimport (\n \"cloud.google.com/go/pubsub\"\n)\n\ntype Handler struct {\n HandleMessage(m pubsub.Message) error\n}\n
Invalid mock generated without this parameter (points to an internal
folder):
Goimport (\n mock \"github.com/stretchr/testify/mock\"\n\n pubsub \"cloud.google.com/go/internal/pubsub\"\n)\n\nfunc (_m *Handler) HandleMessage(m pubsub.Message) error {\n // ...\n return nil\n}\n
Correct mock generated with this parameter.
Goimport (\n mock \"github.com/stretchr/testify/mock\"\n\n pubsub \"cloud.google.com/go/pubsub\"\n)\n\nfunc (_m *Handler) HandleMessage(m pubsub.Message) error {\n // ...\n return nil\n}\n
Generic type constraints can also be replaced by targeting the changed parameter with the square bracket notation on the left-hand side.
Bashmockery --replace-type github.com/vektra/mockery/v2/baz/internal/foo.InternalBaz[T]=github.com/vektra/mockery/v2/baz.Baz\n
For example:
Gotype InternalBaz[T any] struct{}\n\nfunc (*InternalBaz[T]) Foo() T {}\n\n// Becomes\ntype InternalBaz[T baz.Baz] struct{}\n\nfunc (*InternalBaz[T]) Foo() T {}\n
If a type constraint needs to be removed and replaced with a type, target the constraint with square brackets and include a '-' in front to have it removed.
Bashmockery --replace-type github.com/vektra/mockery/v2/baz/internal/foo.InternalBaz[-T]=github.com/vektra/mockery/v2/baz.Baz\n
For example:
Gotype InternalBaz[T any] struct{}\n\nfunc (*InternalBaz[T]) Foo() T {}\n\n// Becomes\ntype InternalBaz struct{}\n\nfunc (*InternalBaz) Foo() baz.Baz {}\n
When replacing a generic constraint, you can replace the type with a pointer by adding a '*' before the output type name.
Bashmockery --replace-type github.com/vektra/mockery/v2/baz/internal/foo.InternalBaz[-T]=github.com/vektra/mockery/v2/baz.*Baz\n
For example:
Gotype InternalBaz[T any] struct{}\n\nfunc (*InternalBaz[T]) Foo() T {}\n\n// Becomes\ntype InternalBaz struct{}\n\nfunc (*InternalBaz) Foo() *baz.Baz {}\n
"},{"location":"features/#packages-configuration","title":"packages
configuration","text":" v2.21.0
Info
See the Migration Docs on how to migrate to this new feature.
Mockery has a configuration parameter called packages
. In this config section, you define the packages and the interfaces you want mocks generated for. The packages can be any arbitrary package, either your own project or anything within the Go ecosystem. You may provide package-level or interface-level overrides to the default config you provide.
Usage of the packages
config section is desirable for multiple reasons:
- Up to 5x increase in mock generation speed over the legacy method
- Granular control over interface generation, location, and file names
- Singular location for all config, instead of spread around by
//go:generate
statements - Clean, easy to understand.
"},{"location":"features/#examples","title":"Examples","text":"Here is an example configuration set:
YAMLwith-expecter: True\npackages:\n github.com/vektra/mockery/v2/pkg: # (1)!\n interfaces:\n TypesPackage:\n RequesterVariadic:\n config: # (2)!\n with-expecter: False \n configs:\n - mockname: MockRequesterVariadicOneArgument\n unroll-variadic: False\n - mockname: MockRequesterVariadic\n io:\n config:\n all: True # (3)!\n interfaces:\n Writer:\n config:\n with-expecter: False # (4)!\n
- For this package, we provide no package-level config (which means we inherit the defaults at the top-level). Since our default of
all:
is False
, mockery will only generate the interfaces we specify. We tell it which interface to generate by using the interfaces
section and specifying an empty map, one for each interface. - There might be cases where you want multiple mocks generated from the same interface. To do this, you can define a default
config
section for the interface, and further configs
(plural) section, one for each mock. You must specify a mockname
for the mocks in this section to differentiate them. - This is telling mockery to generate all interfaces in the
io
package. - We can provide interface-specific overrides to the generation config.
"},{"location":"features/#templated-variables","title":"Templated variables","text":"Note
Templated variables are only available when using the packages
config feature.
Included with this feature is the ability to use templated strings for various configuration options. This is useful to define where your mocks are placed and how to name them. You can view the template variables available in the Configuration section of the docs.
"},{"location":"features/#recursive-package-discovery","title":"Recursive package discovery","text":" v2.25.0
When recursive: true
is set on a particular package:
YAMLpackages:\n github.com/user/project:\n config:\n recursive: true\n with-expecter: true\n
mockery will dynamically discover all sub-packages within the specified package. This is done by calling packages.Load
on the specified package, which induces Go to download the package from the internet (or simply your local project). Mockery then recursively discovers all sub-directories from the root package that also contain .go
files and injects the respective package path into the config map as if you had specified them manually. As an example, your in-memory config map may end up looking like this:
YAMLpackages:\n github.com/user/project:\n config:\n recursive: true\n with-expecter: true\n github.com/user/project/subpkg1:\n config:\n recursive: true\n with-expecter: true\n github.com/user/project/subpkg2:\n config:\n recursive: true\n with-expecter: true\n
You can use the showconfig
command to see the config mockery injects. The output of showconfig
theoretically could be copy-pasted into your YAML file as it is semantically equivalent.
mockery will not recurse into submodules, i.e. any subdirectory that contains a go.mod file. You must specify the submodule as a separate line item in the config if you would like mocks generated for it as well.
performance characteristics The performance when using recursive: true
may be worse than manually specifying all packages statically in the YAML file. This is because of the fact that mockery has to recursively walk the filesystem path that contains the package in question. It may unnecessarily walk down unrelated paths (for example, a Python virtual environment that is in the same path as your package). For this reason, it is recommended not to use recursive: true
if it can be avoided.
"},{"location":"features/#regex-matching","title":"Regex matching","text":"You can filter matched interfaces using the include-regex
option. To generate mocks only for interfaces ending in Client
we can use the following configuration:
YAMLpackages:\n github.com/user/project:\n config:\n recursive: true\n include-regex: \".*Client\"\n
To further refine matched interfaces, you can also use exclude-regex
. If an interface matches both include-regex
and exclude-regex
then it will not be generated. For example, to generate all interfaces except those ending in Func
:
YAMLpackages:\n github.com/user/project:\n config:\n recursive: true\n include-regex: \".*\"\n exclude-regex: \".*Func\"\n
You can only use exclude-regex
with include-regex
. If set by itself, exclude-regex
has no effect.
all: true Using all: true
will override include-regex
(and exclude-regex
) and issue a warning.
"},{"location":"features/#mock-constructors","title":"Mock Constructors","text":" 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{}\nfactory.Test(t) // so that mock does not panic when a method is unexpected\ndefer factory.AssertExpectations(t)\n
Instead, you may simply use the constructor: Go
factory := mocks.NewFactory(t)\n
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.
"},{"location":"features/#expecter-structs","title":"Expecter Structs","text":" v2.10.0 \u00b7 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 {\n Get(path string) (string, error)\n}\n
You can use the expecter interface as such: Go
requesterMock := mocks.NewRequester(t)\nrequesterMock.EXPECT().Get(\"some path\").Return(\"result\", nil)\n
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.
GorequesterMock.EXPECT().\n Get(mock.Anything).\n RunAndReturn(func(path string) (string, error) { \n fmt.Println(path, \"was called\")\n return (\"result for \" + path), nil\n })\n
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.
"},{"location":"features/#return-value-providers","title":"Return Value Providers","text":" 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:
Gotype Proxy interface {\npassthrough(ctx context.Context, s string) (string, error)\n}\n
First form:
GoproxyMock := mocks.NewProxy(t)\nproxyMock.On(\"passthrough\", mock.AnythingOfType(\"context.Context\"), mock.AnythingOfType(\"string\")).\nReturn(\n func(ctx context.Context, s string) (string, error) {\n return s, nil\n }\n)\n
Second form:
GoproxyMock := mocks.NewProxy(t)\nproxyMock.On(\"passthrough\", mock.AnythingOfType(\"context.Context\"), mock.AnythingOfType(\"string\")).\nReturn(\n func(ctx context.Context, s string) string {\n return s\n },\n func(ctx context.Context, s string) error {\n return nil\n },\n)\n
"},{"location":"installation/","title":"Getting Started","text":""},{"location":"installation/#installation","title":"Installation","text":""},{"location":"installation/#github-release-recommended","title":"GitHub Release recommended","text":"Visit the releases page to download one of the pre-built binaries for your platform.
"},{"location":"installation/#go-install","title":"go install","text":"Supported, but not recommended: see wiki page and related discussions.
Warning
Do not use @latest
as this will pull from the latest, potentially untagged, commit on master.
"},{"location":"installation/#docker","title":"Docker","text":"Use the Docker image
Text Onlydocker pull vektra/mockery\n
Generate all the mocks for your project:
Text Onlydocker run -v \"$PWD\":/src -w /src vektra/mockery --all\n
"},{"location":"installation/#homebrew","title":"Homebrew","text":"Install through brew
Text Onlybrew install mockery\nbrew upgrade mockery\n
"},{"location":"migrating_to_packages/","title":"Migrating To Packages","text":"The packages feature is a new configuration scheme that aims to simplify and improve a lot of legacy behavior. This will be the only way to generate mocks in v3. These docs outline general principles for migrating to the new scheme.
"},{"location":"migrating_to_packages/#background","title":"Background","text":"mockery was built during the pre-module era of Golang. Much of its codebase and configuration syntax was designed around file-based operations. This model became highly inefficient once Golang migrated to module-based packages. The old configuration semantics also proved limiting -- many users introduced and requested feature additions to mockery to support esoteric use-cases. This proved to be a huge maintenance burden that existed solely because the configuration model could not flexibly describe all the situations users wanted. The packages
semantics provides us a few highly desirable traits:
- Orders of magnitude performance increase, due to calling
packages.Load
once or twice for an entire project, versus once per file in the legacy semantics. - Hierarchical configuration model that allows interface-specific config to be inherited from package-level config, which is inherited from defaults.
- Single configuration file that describes the entirety of mockery's behavior, instead of spread out by
//go:generate
statements. - Extensive and flexible usage of a Golang string templating environment that allows users to dynamically specify parameter values.
"},{"location":"migrating_to_packages/#configuration-changes","title":"Configuration Changes","text":"The existence of the packages:
map in your configuration acts as a feature flag that enables the feature.
The configuration parameters used in packages
should be considered to have no relation to their meanings in the legacy scheme. It is recommended to wipe out all previous configuration and command-line parameters previously used.
The configuration docs show the parameters that are available for use in the packages
scheme. You should only use the parameters shown in this section. Mockery will not prevent you from using the legacy parameter set, but doing so will result in undefined behavior.
All of the parameters in the config section can be specified at the top level of the config file, which serves as the default values. The packages
config section defines package-specific config. See some examples here.
"},{"location":"migrating_to_packages/#examples","title":"Examples","text":""},{"location":"migrating_to_packages/#separate-mocks-directory","title":"Separate mocks/
directory","text":"Take for example a configuration where you are specifying all: true
at the top of your repo, and you're placing your mocks in a separate mocks/
directory, mirroring the directory structure of your original repo.
YAMLtestonly: False\nwith-expecter: True\nkeeptree: True\nall: True\n
The equivalent config for packages
looks like this:
YAMLwith-expecter: True\ndir: mocks/{{ replaceAll .InterfaceDirRelative \"internal\" \"internal_\" }} #(1)!\nmockname: \"{{.InterfaceName}}\"\noutpkg: \"{{.PackageName}}\"\nfilename: \"{{.InterfaceName}}.go\"\nall: True\npackages:\n github.com/org/repo:\n config:\n recursive: True\n
- The use of
replaceAll
is a trick that is done to ensure mocks created for internal
packages can be imported outside the mock directory. This retains the behavior of the legacy config.
While the example config provided here is more verbose, that is because we're specifying many non-default values in order to retain strict equivalence for this example. It's recommended to refer to the configuration parameters to see the defaults provided.
"},{"location":"migrating_to_packages/#adjacent-to-interface","title":"Adjacent to interface","text":"Another common pattern in the legacy config is to place mocks next to the file that defined the interface.
YAMLwith-expecter: True\ninpackage: True\nall: True\n
For example, the mock file would be laid out like:
Text Only./getter.go\n./mock_Getter.go\n
The equivalent config would look like:
YAMLwith-expecter: True\ninpackage: True\ndir: \"{{.InterfaceDir}}\"\nmockname: \"Mock{{.InterfaceName}}\"\noutpkg: \"{{.PackageName}}\"\nfilename: \"mock_{{.InterfaceName}}.go\"\nall: True\npackages:\n github.com/org/repo:\n config:\n recursive: True\n
"},{"location":"migrating_to_packages/#gogenerate-directives","title":"//go:generate
directives","text":"Previously, the recommended way of generating mocks was to call mockery
once per interface using //go:generate
. Generating interface-specific mocks this way is no longer supported. You may still use //go:generate
to call mockery, however it will generate all interfaces defined in your config file. There currently exists no semantics to specify the generation of specific interfaces from the command line (not because we reject the idea, but because it was not seen as a requirement for the initial iteration of packages
).
"},{"location":"migrating_to_packages/#behavior-changes","title":"Behavior Changes","text":"The legacy behavior iterated over every .go
file in your project, called packages.Load
to parse the syntax tree, and generated mocks for every interface found in the file. The new behavior instead simply grabs the list of packages to load from the config file, or in the case of recursive: True
, walks the file-system tree to discover the packages that exist (without actually parsing the files). Using this list, it calls packages.Load
once with the list of packages that were discovered.
"},{"location":"migrating_to_packages/#filesystem-tree-layouts","title":"Filesystem Tree Layouts","text":"The legacy config provided the inpackage
parameter which, if inpackage: True
, would place the mocks in the same package as your interfaces. Otherwise, it would place it in a separate directory.
These two layouts are supported in the packages
scheme. See the relevant docs here.
"},{"location":"notes/","title":"Frequently Asked Questions","text":""},{"location":"notes/#error-no-go-files-found-in-root-search-path","title":"error: no go files found in root search path
","text":"When using the packages
feature, recursive: true
and you have specified a package that contains no *.go
files, mockery is unable to determine the on-disk location of the package in order to continue the recursive package search. This appears to be a limitation of the golang.org/x/tools/go/packages package that is used to parse package metadata.
The solution is to create a .go
file in the package's path and add a package [name]
directive at the top. It doesn't matter what the file is called. This allows mockery to properly read package metadata.
Discussion
"},{"location":"notes/#internal-error-package-without-types-was-imported","title":"internal error: package without types was imported","text":"https://github.com/vektra/mockery/issues/475
This issue indicates that you have attempted to use package in your dependency tree (whether direct or indirect) that uses Go language semantics that your currently-running Go version does not support. The solution:
- Update to the latest go version
- Delete all cached packages with
go clean -modcache
- Reinstall mockery
Additionally, this issue only happens when compiling mockery from source, such as with go install
. Our docs recommend not to use go install
as the success of your build depends on the compatibility of your Go version with the semantics in use. You would not encounter this issue if using one of the installation methods that install pre-built binaries, like downloading the .tar.gz
binaries, or through brew install
.
"},{"location":"notes/#multiple-expectations-with-identical-arguments","title":"Multiple Expectations With Identical Arguments","text":"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\ngetter := NewGetter()\nassert(t, \"foo\", getter.Get(\"key\"))\n\n// Return \"bar\" on the second call\nassert(t, \"bar\", getter.Get(\"key\"))\n
This can be done by using the .Once()
method on the mock call expectation:
GomockGetter := NewMockGetter(t)\nmockGetter.EXPECT().Get(mock.anything).Return(\"foo\").Once()\nmockGetter.EXPECT().Get(mock.anything).Return(\"bar\").Once()\n
Or you can identify an arbitrary number of times each value should be returned:
GomockGetter := NewMockGetter(t)\nmockGetter.EXPECT().Get(mock.anything).Return(\"foo\").Times(4)\nmockGetter.EXPECT().Get(mock.anything).Return(\"bar\").Times(2)\n
Note that with proper Go support in your IDE, all the available methods are self-documented in autocompletion help contexts.
"},{"location":"notes/#variadic-arguments","title":"Variadic Arguments","text":"Consider if we have a function func Bar(message ...string) error
. A typical assertion might look like this:
Gofunc TestFoo(t *testing.T) {\n m := NewMockFoo(t)\n m.On(\"Bar\", \"hello\", \"world\").Return(nil)\n
We might also want to make an assertion that says \"any number of variadic arguments\":
Gom.On(\"Bar\", mock.Anything).Return(nil)\n
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:
Gom.On(\"Bar\", mock.Anything).Return(nil)\n
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:
Gom.On(\"Bar\", mock.Anything).Return(nil)\n
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\nm.On(\"Bar\", mock.Anything).Return(nil)\n// case 2\nm.On(\"Bar\", []interface{}{mock.Anything}).Return(nil)\n
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
"},{"location":"notes/#semantic-versioning","title":"Semantic Versioning","text":"The versioning in this project applies only to the behavior of the mockery binary itself. This project explicitly does not promise a stable internal API, but rather a stable executable. The versioning applies to the following:
- CLI arguments.
- Parsing of Go code. New features in the Go language will be supported in a backwards-compatible manner, except during major version bumps.
- Behavior of mock objects. Mock objects can be considered to be part of the public API.
- Behavior of mockery given a set of arguments.
What the version does not track:
- The interfaces, objects, methods etc. in the vektra/mockery package.
- Compatibility of
go get
-ing mockery with new or old versions of Go.
"},{"location":"notes/#mocking-interfaces-in-main","title":"Mocking interfaces in main
","text":"When your interfaces are in the main package, you should supply the --inpackage
flag. This will generate mocks in the same package as the target code, avoiding import issues.
"},{"location":"notes/#mockery-fails-to-run-when-mockery_version-environment-variable-is-set","title":"mockery fails to run when MOCKERY_VERSION
environment variable is set","text":"This issue was first highlighted in this GitHub issue.
mockery uses the viper package for configuration mapping and parsing. Viper is set to automatically search for all config variables specified in its config struct. One of the config variables is named version
, which gets mapped to an environment variable called MOCKERY_VERSION
. If you set this environment variable, mockery attempts to parse it into the version
bool config.
This is an adverse effect of how our config parsing is set up. The solution is to rename your environment variable to something other than MOCKERY_VERSION
.
"},{"location":"running/","title":"Running","text":"If your .mockery.yaml
file has been populated with the packages and interfaces you want mocked, mockery can be run with no arguments. Take for example how the mockery project itself is configured:
YAMLquiet: False\nkeeptree: True\ndisable-version-string: True\nwith-expecter: True\nmockname: \"{{.InterfaceName}}\"\nfilename: \"{{.MockName}}.go\"\noutpkg: mocks\npackages:\n github.com/vektra/mockery/v2/pkg:\n interfaces:\n TypesPackage:\n# Lots more config...\n
From anywhere within your repo, you can simply call mockery
once, and it will find your config either by respecting the config
path you gave it, or by searching upwards from the current working directory.
Bashmockery\n08 Jul 23 01:40 EDT INF Starting mockery dry-run=false version=v2.31.0\n08 Jul 23 01:40 EDT INF Using config: /Users/landonclipp/git/LandonTClipp/mockery/.mockery.yaml dry-run=false version=v2.31.0\n
Command line arguments
It is valid to specify arguments from the command line. The configuration precedence is specified in the Configuration docs.
"}]}
\ No newline at end of file