build/make/mocks.mk uses mockery v3.
mockery v3 no longer supports CLI flags like --all --dir; everything is controlled via the configuration file.
Therefore the configuration now belongs entirely to the repository: the makefiles only provide the tool and the make targets.
make mocks aborts with an error if no .mockery.yaml exists in the repository root.
| Target | Description |
|---|---|
make mocks |
Generates the mocks configured in .mockery.yaml. |
make mocks-init |
Creates a .mockery.yaml with our defaults. Refuses to overwrite an existing file. |
make mocks-delete |
Deletes all Go files containing the header Code generated by mockery. |
make mocks does not delete old mocks. To regenerate from scratch, run make mocks-delete mocks.
Update the makefiles to the version with mockery v3 support (make self-update).
If your Makefile overrides the mocks target, remove that override.
If it sets MOCKERY_VERSION to a v2 version or overrides MOCKERY_IGNORED, remove those as well.
A leftover v2 MOCKERY_VERSION shows up as a failing checksum (sha256sum: WARNING: 1 computed checksum did NOT match),
because the v2 archive is checked against the v3 checksum.
There are two ways:
- Start fresh: move the old
.mockery.yamlaway and runmake mocks-init. - Translate the existing v2 configuration: run
.bin/mockery migrate --config .mockery.yaml.- The result is written to
.mockery_v3.yml. mockery v3 does not find this file name when looking up its configuration, so rename it to.mockery.yaml. - The command is "not comprehensive and likely has missing edge cases" according to the
mockery documentation.
replace-typeis not translated at all. - It prints a table of deprecated keys. Go through it.
- The result is written to
Check these points by hand, even after mockery migrate:
-
Set
filenametomocks_test.go. We generate one mock file per package.mockery migratekeeps the old one-file-per-interface pattern. -
mocknameis now calledstructname,outpkgis now calledpkgname. -
Remove
with-expecter(always active in v3),testonly(the_test.goproperty now results fromfilenameonly),inpackageandkeeptree. -
excludeis nowexclude-subpkg-regex,exclude-regexis nowexclude-interface-regex,include-regexis nowinclude-interface-regex. -
boilerplate-file,mock-build-tagsandunroll-variadicmove belowtemplate-data. -
Check whether your tests rely on unrolled variadic arguments. v2 unrolled them by default, v3 does not, and the template does not set it either. If tests use expectations like
EXPECT().List(ctx, list, labels)for a variadic method, they compile, but fail at runtime withmock: Unexpected Method Call, because the mock passes the variadic arguments as one slice. In that case add:template-data: unroll-variadic: true
-
resolve-type-aliasis alwaysfalsein v3 (the v2 default wastrue). -
Add
vendortoexclude-subpkg-regexif the repository has a vendoredvendor/directory. -
The
packages:block is mandatory and must contain the module path of the repository (seego list -m).
The template build/make/mockery.yaml.tpl shows our defaults.
In a repository with a go.work and several modules, use one .mockery.yaml in the repository root
instead of one per module. It lists every module below packages:; mockery loads them through the
workspace and still writes the mocks next to the interfaces in the respective module:
packages:
github.com/cloudogu/maintenance-assets:
config: {}
github.com/cloudogu/warp-assets:
config: {}make mocks-init creates this block automatically from go list -m. Delete the per-module
.mockery.yaml files and the custom mocks target that changed into each module directory.
The template sets structname: "{{.Mock}}{{.InterfaceName | firstUpper }}". It produces the same names
as the usual v2 setting mockname: "{{.Mock}}{{.InterfaceName | camelcase }}", e.g. mockLocalDoguFetcher
for the unexported interface localDoguFetcher and MockDependencyValidator for DependencyValidator.
make mocks-deleteThis step is mandatory: the old mock_*_test.go files declare the same types as the new
mocks_test.go, so the package would no longer compile.
make mocksRun the tests, review the diff and commit the new .mockery.yaml together with the generated mocks.
The template sets template: testify, which generates the mocks with EXPECT() that all our tests use.
mockery v3 also provides the matryer template.
It generates moq-style mocks: a struct with one func field per method and a list of recorded calls, without a dependency on testify:
Switching an existing package to matryer means rewriting all tests that use EXPECT().
The template can also be set per package, so new packages can use matryer while existing ones keep testify.
packages:
github.com/cloudogu/my-module:
config: {}
github.com/cloudogu/my-module/newpackage:
config:
template: matryer| Variable | Default | Description |
|---|---|---|
MOCKERY_VERSION |
v3.8.0 |
mockery version. Changing it also requires MOCKERY_SUM. |
MOCKERY_URL |
release asset for linux/x86_64 | Download URL of the release archive. |
MOCKERY_SUM |
sha256 of the linux/x86_64 asset | Checksum of the release archive (see checksum.txt of the release). |
If the installed binary in .bin/mockery does not match MOCKERY_VERSION, it is downloaded again.