manage your mocks / run mockgen more quickly / mocks up-to-date checking

gomockhandler

If you find any bugs or have feature requests, please feel free to create an issue.

gomockhandler is handler of golang/mock, as the name implies.

gomockhandler use 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 ๐Ÿ“š .

Here is some example of the mock being generated in half the time with gomockhandler. (I ran mockgen to generate same mocks in go generate ./...)

Screen Shot 2021-03-25 at 11 55 54

Screen Shot 2021-03-25 at 11 56 29

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.

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 version < 1.16

GO111MODULE=on go get github.com/golang/mock/mockgen
GO111MODULE=on go get github.com/sanposhiho/gomockhandler

Go 1.16+

go install github.com/golang/mock/mockgen
go install github.com/sanposhiho/gomockhandler

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
-config string
  The path to config file.
  The default value is "./gomockhandler.json"

configuring

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 CLI. It will also check if mockgen will run correctly with that option.

If a config file does not exist, a config file will be created.

(It is RECOMMENDED to name the config file gomockhandler.json, and place it in a location where the gomockhandler is likely to be run frequently.)

mockgen has two modes of operation: source and reflect, and gomockhandler support both.

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

You can use all options of mockgen to add a new mock.

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/

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.

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 

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": "7E+SZ7+e0tK5wBe15dJLvA==",
			"mode": "SOURCE_MODE",
			"source_mode_runner": {
				"source": "interfaces/user.go",
				"destination": "mock/user.go"
			}
		},
		"mock/user2.go": {
			"checksum": "BEqA5NiFCJa3De8kKXYf3g==",
			"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.

Owner
Kensei Nakada
Backend developer w/ Elixir, Go
Kensei Nakada
Comments
  • find un-managed mocks

    find un-managed mocks

    This PR ensures that the check command has a one-to-one correspondence between gomockhandler.json and the actual mock generated by gomock. In other words, it finds zombie mocks. (A zombie mock is a mock generated by gomock but not managed by gomockhandler.) And It can also find mocks which are managed by gomockhandler but not generated


    Fixes #61

  • the order on generated configuration is randomly changed

    the order on generated configuration is randomly changed

    Currently if we do gomockhandler mockgen order of content randomly changed, although there is no changes. For Example:

    // before
    {
    	"mocks": {
    		"a_mock.go": {
    			"checksum": "xxxxxxxxxxx",
    			"source_checksum": "aaaaaaaaaaaaa",
    			"mode": "SOURCE_MODE",
    			"source_mode_runner": {
    				"source": "a.go",
    				"destination": "a_mock.go",
    				"package": "main"
    			}
    		},
    		"b_mock.go": {
    			"checksum": "yyyyyyyyyyyy",
    			"source_checksum": "bbbbbbbbbbb",
    			"mode": "SOURCE_MODE",
    			"source_mode_runner": {
    				"source": "b.go",
    				"destination": "b_mock.go",
    				"package": "main"
    			}
    		}
    }
    // after
    {
    	"mocks": {
    		"b_mock.go": {
    			"checksum": "yyyyyyyyyyyy",
    			"source_checksum": "bbbbbbbbbbb",
    			"mode": "SOURCE_MODE",
    			"source_mode_runner": {
    				"source": "b.go",
    				"destination": "b_mock.go",
    				"package": "main"
    			}
    		},
    		"a_mock.go": {
    			"checksum": "xxxxxxxxxxx",
    			"source_checksum": "aaaaaaaaaaaaa",
    			"mode": "SOURCE_MODE",
    			"source_mode_runner": {
    				"source": "a.go",
    				"destination": "a_mock.go",
    				"package": "main"
    			}
    		}
    }
    

    This behavior becomes some noise when we manage config file by git. I recommend those contents to be dictionary order to avoid this problem.

    I think the part below leads this phenomenon. https://github.com/sanposhiho/gomockhandler/blob/6247fdf33a84302a90a32bd84a33bff28386351e/internal/model/config_easyjson.go#L87

    Thank you.

  • use bufio.Reader instead of bufio.Scanner

    use bufio.Reader instead of bufio.Scanner

    gomockhandler check is failed when scan the large single line file. Because ~os~ of hard limit of bufio.Scanner.

    So use bufio.Reader to scan first line of file.

    P.S. There is another approach like filtering target files using extension, etc...

  • configuration file is not readable

    configuration file is not readable

    Now, we support configuration gomockhandler.json.

    And to add new mock on config, users have to execute cmd like this, and config for new mock will be added on gomockhandler.json. gomockhandler -config=/path/to/gomockhandler.json -source=foo.go -destination=./mock/ [other mockgen options]

    But, PR reviewers cannot see what command will be registered, and it makes PR review a little hard.

    So, I want to add new optional configuration file or add information on config file to resolve this.

  • Fix Go 1.16 installation on README

    Fix Go 1.16 installation on README

    It would be good to append @latest to the package identifier otherwise we get an error when installing outside of a module:

    > go install github.com/sanposhiho/gomockhandler
    go install: version is required when current directory is not in a module
            Try 'go install github.com/sanposhiho/gomockhandler@latest' to install the latest version
    > go install github.com/sanposhiho/gomockhandler@latest
    # Works as expected
    

    Also, great job on the tool :)

  •  gomockhandler doesn't log error correctly when it fail to run mockgen

    gomockhandler doesn't log error correctly when it fail to run mockgen

    2021/12/10 16:35:40 failed to run: failed to run mockgen: exit status 1
    Please run `%!s(<nil>)` and check if mockgen works correctly with your options
    make: *** [generate] Error 1
    
  • Eliminate the need to install mockgen

    Eliminate the need to install mockgen

    Target version: v1.0

    We cannot call mockgen directly because it is private entry point. https://github.com/golang/mock/blob/master/mockgen/mockgen.go#L68

    But, I think we can make it with gitsubmodule, maybe, maybe... Let's try it.

  • Specify excluded path(s)

    Specify excluded path(s)

    Being able to specify paths ignored by gomockhandler could be useful.

    For example, one of my projects has a vendor folder where code from an external repository is being stored. In that folder, there are mock files. Those are not managed by gomockhandler and therefore, gomockhandler check complains about it. Given that those files come from outside of my project, I don't think having gomockhandler managing them would be a good idea.

  • Eliminate the need to install mockgen

    Eliminate the need to install mockgen

    Let's eliminate the need to install mockgen.


    We currently require users to install it. But, unexpected behaviors may occur due to differences in mockgen behavior depending on which mockgen the user has installed. Ideally, we should generate mocks without using user-installed mockgen and we can achieve that if we can import mockgen.


    But currently, almost all logic of mockgen cannot be imported, because it is placed in main package. So, I propose to fork golang/mock, add changes to make it importable, and use the fork to import mockgen.

    And, I raised the issue for golang/mock. https://github.com/golang/mock/issues/609

  • split gomockhandler.json into configuration file and mocks status file

    split gomockhandler.json into configuration file and mocks status file

    from #59

    Let's move source_checksum and checksum from gomockhandler.json to new 'mocks status file'.

    with this

    • we can make configuration file more readable
    • we can allow user to edit configuration file directly
A toolkit with common assertions and mocks that plays nicely with the standard library

Testify - Thou Shalt Write Tests โ„น๏ธ We are working on testify v2 and would love to hear what you'd like to see in it, have your say here: https://cutt

Dec 30, 2022
Aquatone is a tool for visual inspection of websites across a large amount of hosts and is convenient for quickly gaining an overview of HTTP-based attack surface.

Aquatone is a tool for visual inspection of websites across a large amount of hosts and is convenient for quickly gaining an overview of HTTP-based attack surface.

Jan 6, 2023
siusiu (suite-suite harmonics) a suite used to manage the suite, designed to free penetration testing engineers from learning and using various security tools, reducing the time and effort spent by penetration testing engineers on installing tools, remembering how to use tools.
siusiu (suite-suite harmonics) a suite used to manage the suite, designed to free penetration testing engineers from learning and using various security tools, reducing the time and effort spent by penetration testing engineers on installing tools, remembering how to use tools.

siusiu (suite-suite harmonics) a suite used to manage the suite, designed to free penetration testing engineers from learning and using various security tools, reducing the time and effort spent by penetration testing engineers on installing tools, remembering how to use tools.

Dec 12, 2022
Full-featured test framework for Go! Assertions, mocking, input testing, output capturing, and much more! ๐Ÿ•
Full-featured test framework for Go! Assertions, mocking, input testing, output capturing, and much more! ๐Ÿ•

testza ?? Testza is like pizza for Go - you could life without it, but why should you? Get The Module | Documentation | Contributing | Code of Conduct

Dec 10, 2022
Robust framework for running complex workload scenarios in isolation, using Go; for integration, e2e tests, benchmarks and more! ๐Ÿ’ช

e2e Go Module providing robust framework for running complex workload scenarios in isolation, using Go and Docker. For integration, e2e tests, benchma

Jan 5, 2023
Small program that takes in commands and moves one or more robots around the surface of Mars!

Mars Rover Build and Run the Image Build image from current directory: docker build -t marsrover . Run image interactively: docker run -i marsrover

Jan 2, 2022
What is more efficient value or pointer method receivers in Go?

What is more efficient value or pointer method receivers? A) Why would you think struct is more efficient? You are making single call to fetch struct

Feb 4, 2022
Wise-mars-rover - Write a program that takes in commands and moves one or more robots around the surface of Mars

wise-mars-rover Write a program that takes in commands and moves one or more rob

Feb 9, 2022
Run a real Postgres database locally on Linux, OSX or Windows as part of another Go application or test
Run a real Postgres database locally on Linux, OSX or Windows as part of another Go application or test

embedded-postgres Run a real Postgres database locally on Linux, OSX or Windows as part of another Go application or test. When testing this provides

Dec 27, 2022
Flugel Test Documentation for steps to run and test the automatio
Flugel Test Documentation for steps to run and test the automatio

Flugel Test Documentation Documentation for steps to run and test the automation #Test-01 1 - Local Test Using Terratest (End To End) 1- By runing " t

Nov 13, 2022
How we can run unit tests in parallel mode with failpoint injection taking effect and without injection race

This is a simple demo to show how we can run unit tests in parallel mode with failpoint injection taking effect and without injection race. The basic

Oct 31, 2021
Ritchie CLI is an open-source tool that allows to create, store and share any kind of automation, executing them through command lines, to run operations or start workflows โš™๏ธ ๐Ÿ–ฅ ๐Ÿ’ก
Ritchie CLI is an open-source tool that allows to create, store and share any kind of automation, executing them through command lines, to run operations or start workflows โš™๏ธ ๐Ÿ–ฅ ๐Ÿ’ก

Table of contents 1. About 2. Getting Started i. Installation ii. Initialize rit locally iii. Add your first formulas repository iv. Run the Hello Wor

Dec 29, 2022
Check your internet speed right from your terminal. Built on GOlang using chromedp
Check your internet speed right from your terminal. Built on GOlang using chromedp

adhocore/fast A GO lang command line tool to check internet speed right from the terminal. Uses fast.com through headless chrome. Prerequistie Chrome

Dec 26, 2022
Test your command line interfaces on windows, linux and osx and nodes viรก ssh and docker

Commander Define language independent tests for your command line scripts and programs in simple yaml files. It runs on windows, osx and linux It can

Dec 17, 2022
Record and replay your HTTP interactions for fast, deterministic and accurate tests

go-vcr go-vcr simplifies testing by recording your HTTP interactions and replaying them in future runs in order to provide fast, deterministic and acc

Dec 25, 2022
A Go library help testing your RESTful API application

RESTit A Go micro-framework to help writing RESTful API integration test Package RESTit provides helps to those who want to write an integration test

Oct 28, 2022
Automatically update your Go tests

autogold - automatically update your Go tests autogold makes go test -update automatically update your Go tests (golden files and Go values in e.g. fo

Dec 25, 2022
A next-generation testing tool. Orion provides a powerful DSL to write and automate your acceptance tests

Orion is born to change the way we implement our acceptance tests. It takes advantage of HCL from Hashicorp t o provide a simple DSL to write the acceptance tests.

Aug 31, 2022
Terratest is a Go library that makes it easier to write automated tests for your infrastructure code.

Terratest is a Go library that makes it easier to write automated tests for your infrastructure code. It provides a variety of helper functions and patterns for common infrastructure testing tasks,

Dec 30, 2022