...
1# gomock
2
3[![Build Status][ci-badge]][ci-runs] [![Go Reference][reference-badge]][reference]
4
5gomock is a mocking framework for the [Go programming language][golang]. It
6integrates well with Go's built-in `testing` package, but can be used in other
7contexts too.
8
9## Installation
10
11Once you have [installed Go][golang-install], install the `mockgen` tool.
12
13**Note**: If you have not done so already be sure to add `$GOPATH/bin` to your
14`PATH`.
15
16To get the latest released version use:
17
18### Go version < 1.16
19
20```bash
21GO111MODULE=on go get github.com/golang/mock/mockgen@v1.6.0
22```
23
24### Go 1.16+
25
26```bash
27go install github.com/golang/mock/mockgen@v1.6.0
28```
29
30If you use `mockgen` in your CI pipeline, it may be more appropriate to fixate
31on a specific mockgen version. You should try to keep the library in sync with
32the version of mockgen used to generate your mocks.
33
34## Running mockgen
35
36`mockgen` has two modes of operation: source and reflect.
37
38### Source mode
39
40Source mode generates mock interfaces from a source file.
41It is enabled by using the -source flag. Other flags that
42may be useful in this mode are -imports and -aux_files.
43
44Example:
45
46```bash
47mockgen -source=foo.go [other options]
48```
49
50### Reflect mode
51
52Reflect mode generates mock interfaces by building a program
53that uses reflection to understand interfaces. It is enabled
54by passing two non-flag arguments: an import path, and a
55comma-separated list of symbols.
56
57You can use "." to refer to the current path's package.
58
59Example:
60
61```bash
62mockgen database/sql/driver Conn,Driver
63
64# Convenient for `go:generate`.
65mockgen . Conn,Driver
66```
67
68### Flags
69
70The `mockgen` command is used to generate source code for a mock
71class given a Go source file containing interfaces to be mocked.
72It supports the following flags:
73
74- `-source`: A file containing interfaces to be mocked.
75
76- `-destination`: A file to which to write the resulting source code. If you
77 don't set this, the code is printed to standard output.
78
79- `-package`: The package to use for the resulting mock class
80 source code. If you don't set this, the package name is `mock_` concatenated
81 with the package of the input file.
82
83- `-imports`: A list of explicit imports that should be used in the resulting
84 source code, specified as a comma-separated list of elements of the form
85 `foo=bar/baz`, where `bar/baz` is the package being imported and `foo` is
86 the identifier to use for the package in the generated source code.
87
88- `-aux_files`: A list of additional files that should be consulted to
89 resolve e.g. embedded interfaces defined in a different file. This is
90 specified as a comma-separated list of elements of the form
91 `foo=bar/baz.go`, where `bar/baz.go` is the source file and `foo` is the
92 package name of that file used by the -source file.
93
94- `-build_flags`: (reflect mode only) Flags passed verbatim to `go build`.
95
96- `-mock_names`: A list of custom names for generated mocks. This is specified
97 as a comma-separated list of elements of the form
98 `Repository=MockSensorRepository,Endpoint=MockSensorEndpoint`, where
99 `Repository` is the interface name and `MockSensorRepository` is the desired
100 mock name (mock factory method and mock recorder will be named after the mock).
101 If one of the interfaces has no custom name specified, then default naming
102 convention will be used.
103
104- `-self_package`: The full package import path for the generated code. The
105 purpose of this flag is to prevent import cycles in the generated code by
106 trying to include its own package. This can happen if the mock's package is
107 set to one of its inputs (usually the main one) and the output is stdio so
108 mockgen cannot detect the final output package. Setting this flag will then
109 tell mockgen which import to exclude.
110
111- `-copyright_file`: Copyright file used to add copyright header to the resulting source code.
112
113- `-debug_parser`: Print out parser results only.
114
115- `-exec_only`: (reflect mode) If set, execute this reflection program.
116
117- `-prog_only`: (reflect mode) Only generate the reflection program; write it to stdout and exit.
118
119- `-write_package_comment`: Writes package documentation comment (godoc) if true. (default true)
120
121For an example of the use of `mockgen`, see the `sample/` directory. In simple
122cases, you will need only the `-source` flag.
123
124## Building Mocks
125
126```go
127type Foo interface {
128 Bar(x int) int
129}
130
131func SUT(f Foo) {
132 // ...
133}
134
135```
136
137```go
138func TestFoo(t *testing.T) {
139 ctrl := gomock.NewController(t)
140
141 // Assert that Bar() is invoked.
142 defer ctrl.Finish()
143
144 m := NewMockFoo(ctrl)
145
146 // Asserts that the first and only call to Bar() is passed 99.
147 // Anything else will fail.
148 m.
149 EXPECT().
150 Bar(gomock.Eq(99)).
151 Return(101)
152
153 SUT(m)
154}
155```
156
157If you are using a Go version of 1.14+, a mockgen version of 1.5.0+, and are
158passing a *testing.T into `gomock.NewController(t)` you no longer need to call
159`ctrl.Finish()` explicitly. It will be called for you automatically from a self
160registered [Cleanup](https://pkg.go.dev/testing?tab=doc#T.Cleanup) function.
161
162## Building Stubs
163
164```go
165type Foo interface {
166 Bar(x int) int
167}
168
169func SUT(f Foo) {
170 // ...
171}
172
173```
174
175```go
176func TestFoo(t *testing.T) {
177 ctrl := gomock.NewController(t)
178 defer ctrl.Finish()
179
180 m := NewMockFoo(ctrl)
181
182 // Does not make any assertions. Executes the anonymous functions and returns
183 // its result when Bar is invoked with 99.
184 m.
185 EXPECT().
186 Bar(gomock.Eq(99)).
187 DoAndReturn(func(_ int) int {
188 time.Sleep(1*time.Second)
189 return 101
190 }).
191 AnyTimes()
192
193 // Does not make any assertions. Returns 103 when Bar is invoked with 101.
194 m.
195 EXPECT().
196 Bar(gomock.Eq(101)).
197 Return(103).
198 AnyTimes()
199
200 SUT(m)
201}
202```
203
204## Modifying Failure Messages
205
206When a matcher reports a failure, it prints the received (`Got`) vs the
207expected (`Want`) value.
208
209```shell
210Got: [3]
211Want: is equal to 2
212Expected call at user_test.go:33 doesn't match the argument at index 1.
213Got: [0 1 1 2 3]
214Want: is equal to 1
215```
216
217### Modifying `Want`
218
219The `Want` value comes from the matcher's `String()` method. If the matcher's
220default output doesn't meet your needs, then it can be modified as follows:
221
222```go
223gomock.WantFormatter(
224 gomock.StringerFunc(func() string { return "is equal to fifteen" }),
225 gomock.Eq(15),
226)
227```
228
229This modifies the `gomock.Eq(15)` matcher's output for `Want:` from `is equal
230to 15` to `is equal to fifteen`.
231
232### Modifying `Got`
233
234The `Got` value comes from the object's `String()` method if it is available.
235In some cases the output of an object is difficult to read (e.g., `[]byte`) and
236it would be helpful for the test to print it differently. The following
237modifies how the `Got` value is formatted:
238
239```go
240gomock.GotFormatterAdapter(
241 gomock.GotFormatterFunc(func(i interface{}) string {
242 // Leading 0s
243 return fmt.Sprintf("%02d", i)
244 }),
245 gomock.Eq(15),
246)
247```
248
249If the received value is `3`, then it will be printed as `03`.
250
251[golang]: http://golang.org/
252[golang-install]: http://golang.org/doc/install.html#releases
253[gomock-reference]: https://pkg.go.dev/github.com/golang/mock/gomock
254[ci-badge]: https://github.com/golang/mock/actions/workflows/test.yaml/badge.svg
255[ci-runs]: https://github.com/golang/mock/actions
256[reference-badge]: https://pkg.go.dev/badge/github.com/golang/mock.svg
257[reference]: https://pkg.go.dev/github.com/golang/mock
258
259## Debugging Errors
260
261### reflect vendoring error
262
263```text
264cannot find package "."
265... github.com/golang/mock/mockgen/model
266```
267
268If you come across this error while using reflect mode and vendoring
269dependencies there are three workarounds you can choose from:
270
2711. Use source mode.
2722. Include an empty import `import _ "github.com/golang/mock/mockgen/model"`.
2733. Add `--build_flags=--mod=mod` to your mockgen command.
274
275This error is due to changes in default behavior of the `go` command in more
276recent versions. More details can be found in
277[#494](https://github.com/golang/mock/issues/494).
View as plain text