gomockhandler
Mr. gomockhandler is the clever and fast manager of mocks generated by uber-go/mock (or golang/mock).
gomockhandler
uses one config file to generate all mocks.
With gomockhandler
,
- You can generate mocks in parallel 🚀.
- You can check if mock is up-to-date ✨.
- You can manage your mocks in one config file 📚.
Background
Some of you may often manage your mocks with go generate
like below.
//go:generate mockgen -source=$GOFILE -destination=mock_$GOFILE -package=$GOPACKAG
But, it will take long time to generate a log of mocks with go generate ./...
, because go generate
executes mockgen
one by one.
And we cannot easily check if mock is up-to-date; people often forget to update mocks when the interface is changed.
gomockhandler
is created to solve all of these problems.
And with this background, it is designed to make it easy to switch from managing mocks with go generate
to managing mocks with gomockhandler.
Install
You have to install mockgen
first.
go install go.uber.org/mock/mockgen@latest
Next, install gomockhandler.
go install github.com/sanposhiho/gomockhandler@latest
How to use
gomockhandler
is designed to be simple and does only three things.
- generate/edit a config with CLI
- generate mocks from config
- check if mocks are up-to-date
These are the options for using the gomockhandler.
-config string
The path to config file.
The default value is "./gomockhandler.json"
-target_dir string
Only mocks under the specified directory will be targeted for commands `check` and `mockgen`.
By default, all files will be targeted.
-f bool
If true, it will also generate mocks whose source has not been updated.
The default value is false.
Getting started
You need a config for gomockhandler
.
However, you don't need to generate/edit the config directly, it can be generated/edited from CLI.
configuring a new mock
You can configure a new mock to be generated with gomockhandler
CLI.
If a gomockhandler config file does not exist, it will be created.
gomockhandler CLI is compatible with mockgen
command which you can do anything you do with mockgen
See golang/mock#running-mockgen for more information about the two modes and mockgen options.
Source mode:
gomockhandler -config=/path/to/gomockhandler.json -source=foo.go -destination=./mock/ [other mockgen options]
Reflect mode:
gomockhandler -config=/path/to/gomockhandler.json -destination=./mock/ [other mockgen options] database/sql/driver Conn,Driver
For example, suppose you want to configure the mock generated by the following mockgen
command to be generated by gomockhandler
mockgen -source=foo.go -destination=../mock/
The following command will add the information of the mock you want to generate to the configuration.
As you can see, you just need to think about the option config
. (The default value is ./gomockhandler.json
)
gomockhandler -config=/path/to/gomockhandler.json -source=foo.go -destination=../mock/
[TIPS] switch from go generate
to gomockhandler
gomockhandler is designed to make it easy to switch from managing mocks with go generate
to managing mocks with gomockhandler.
If you use go:generate
to execute mockgen now, you can generate the config file by rewriting go:generate
comment a little bit.
Replace from mockgen
to gomockhandler -config=/path/to/gomockhandler.json
in all go:generate
comments, and run go generate ./...
in your project. And then,
- //go:generate mockgen -source=$GOFILE -destination=mock_$GOFILE -package=$GOPACKAG
+ //go:generate gomockhandler -config=/path/to/gomockhandler.json -source=$GOFILE -destination=mock_$GOFILE -package=$GOPACKAG
After generating the config, your go:generate
comments are no longer needed. You've been released from a slow-mockgen with go generate
!
Let's delete all go:generate
comments for mockgen in your project.
Recommendations
- name the config file
gomockhandler.json
, and place it in a location where the gomockhandler is likely to be run frequently.
- use Source Mode, if there is no great reason to use Reflect mode., which is much faster because the gomockhandler will skip processing if the source file has not been changed.
delete mocks to be generated from config
You can remove the mocks to be generated from the config.
gomockhandler -config=/path/to/gomockhandler.json -destination=./mock/user.go deletemock
This command only delete the mock from the configuration. So please delete the mock file itself manually.
generate mock
You can generate all mocks from config.
gomockhandler -config=/path/to/gomockhandler.json mockgen
check if mock is up-to-date
You can check if the mock is generated based on the latest interface.
It is useful for ci.
gomockhandler -config=/path/to/gomockhandler.json check
If some mocks are not up to date, you can see the error and gomockhandler
will exit with exit-code 1
2021/03/10 22:17:12 [WARN] mock is not up to date. source: ./interfaces/user.go, destination: ./interfaces/../mock/user.go
2021/03/10 22:17:12 mocks is not up-to-date
edit config manually
You can edit the config manually.
But, it is RECOMMENDED to use CLI, especially for adding/editing mocks. (This is because CLI will check if mockgen works correctly with that option, and then edit the config.)
The config json file has the following format.
{
"mocks": {
"mock/user.go": {
"checksum": "qxZ/pLjLBtib7o+kDLOzOQ==",
"source_checksum": "UUyR0gaRX4IbPPAttwOCXw==",
"mode": "SOURCE_MODE",
"source_mode_runner": {
"source": "interfaces/user.go",
"destination": "mock/user.go"
}
},
"mock/user2.go": {
"checksum": "qxZ/pLjLBtib7o+kDLOzOQ==",
"source_checksum": "AAAAAAAAAAAAAAAAAAAAAA==",
"mode": "REFLECT_MODE",
"reflect_mode_runner": {
"package_name": "playground/interfaces",
"interfaces": "User2",
"destination": "mock/user2.go"
}
}
}
}
As mentioned above, there are two modes of mockgen, and the format of the config is slightly different depending on which mode you are using.
In the ***mode-runner
field, specify the option to be used when running mockgen.
In the checksum
field, the checksum of the currently generated mock is stored. With this checksum, the gomockhandler checks if the mock is the same as the mock generated from the latest interface.
In the source_checksum
field, the checksum of the currently generated mock's source file is stored. This field is only valid in source mode, and when reflect mode is used, the value will be AAAAAAAAAAAAAAAAAAAAAA==
.
contributing
see CONTRIBUTING.md