Skip to content

Commit fa81846

Browse files
committed
Add support for generating gomock mocks
1 parent 6361a70 commit fa81846

19 files changed

+2503
-5
lines changed

.mockery_gomock.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
template: gomock
2+
structname: "GoMock{{.InterfaceName}}"
3+
filename: "mocks_gomock_{{.SrcPackageName}}_test.go"
4+
5+
all: false
6+
template-data:
7+
typed: True
8+
boilerplate-file: "./.boilerplate.txt"
9+
packages:
10+
github.com/vektra/mockery/v3/internal/fixtures:
11+
interfaces:
12+
Requester:
13+
github.com/vektra/mockery/v3/internal/fixtures/empty_return:
14+
interfaces:
15+
EmptyReturn:
16+
io:
17+
config:
18+
all: True
19+
dir: internal/fixtures/
20+
pkgname: test

Taskfile.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,16 @@ tasks:
3636
cmds:
3737
- MOCKERY_CONFIG=./.mockery_matryer.yml go run .
3838

39+
mocks.generate.gomock:
40+
cmds:
41+
- MOCKERY_CONFIG=./.mockery_gomock.yml go run .
42+
3943
mocks.generate:
4044
desc: generate mocks
4145
deps:
4246
- mocks.generate.mockery
4347
- mocks.generate.matryer
48+
- mocks.generate.gomock
4449

4550
docker:
4651
desc: build the mockery docker image

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func Test_getFromDB(t *testing.T) {
6767
Why use mockery?
6868
----------------
6969

70-
1. You gain access to a number of pre-curated mock implementations that can be used in testing. This includes traditional "mockery-style" mocks, as well as other styles from the open source community such as from https://github.com/matryer/moq. Such mocks allow you to quickly define how the implementation should behave under test without having to manually curate your own mocks/stubs/fakes.
70+
1. You gain access to a number of pre-curated mock implementations that can be used in testing. This includes traditional "mockery-style" mocks, as well as other styles from the open source community such as from https://github.com/matryer/moq or https://github.com/uber-go/mock. Such mocks allow you to quickly define how the implementation should behave under test without having to manually curate your own mocks/stubs/fakes.
7171
2. Mockery benefits from a large number of performance improvements that almost all other Go code-generation projects currently have not employed. This means that it's orders of magnitude faster for large codebases.
7272
3. Mockery provides a comprehensive, centralized, flexible, and simple configuration scheme driven off of yaml instead of relying on sprawling `//go:generate` commands.
7373
4. Mockery is a code-generation framework. While its original goal is to provide mock implementations for testing purposes, users can supply their own templates to auto-generate any kind of code that needs to be based off of interfaces.

docs/template/gomock.md

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
---
2+
title: gomock
3+
---
4+
5+
`gomock` mocks are derived from the project at https://github.com/uber-go/mock.
6+
7+
## Description
8+
9+
=== "Interface"
10+
11+
```go
12+
package test
13+
14+
type Requester interface {
15+
Get(path string) (string, error)
16+
}
17+
```
18+
19+
20+
=== "Example Usage"
21+
22+
```go
23+
package test
24+
25+
import (
26+
"testing"
27+
28+
"github.com/stretchr/testify/assert"
29+
)
30+
31+
func TestRequesterGoMock(t *testing.T) {
32+
ctrl := gomock.NewController(t)
33+
m := NewGoMockRequester(ctrl)
34+
m.EXPECT().Get("foo").Return("bar", nil).Times(1)
35+
retString, err := m.Get("foo")
36+
assert.NoError(t, err)
37+
assert.Equal(t, "bar", retString)
38+
}
39+
```
40+
41+
=== "`.mockery.yml`"
42+
43+
```yaml
44+
template: gomock
45+
template-data:
46+
typed: true
47+
packages:
48+
github.com/vektra/mockery/v3/pkg/fixtures:
49+
config:
50+
dir: "{{.InterfaceDir}}"
51+
filename: "gomocks.go"
52+
pkgname: "test"
53+
structname: "GoMock{{.InterfaceName}}"
54+
interfaces:
55+
Requester:
56+
```
57+
58+
=== "`mocks_gomock.go`"
59+
60+
```go
61+
// Code generated by mockery; DO NOT EDIT.
62+
// github.com/vektra/mockery
63+
// template: gomock
64+
// source: github.com/vektra/mockery/v3/internal/fixtures (interfaces: Requester)
65+
66+
// Package test is a generated GoMock package.
67+
package test
68+
69+
import (
70+
"reflect"
71+
72+
"go.uber.org/mock/gomock"
73+
)
74+
75+
// GoMockRequester is a mock of Requester interface.
76+
type GoMockRequester struct {
77+
ctrl *gomock.Controller
78+
recorder *GoMockRequesterMockRecorder
79+
isgomock struct{}
80+
}
81+
82+
// GoMockRequesterMockRecorder is the mock recorder for GoMockRequester.
83+
type GoMockRequesterMockRecorder struct {
84+
mock *GoMockRequester
85+
}
86+
87+
// NewGoMockRequester creates a new mock instance.
88+
func NewGoMockRequester(ctrl *gomock.Controller) *GoMockRequester {
89+
mock := &GoMockRequester{ctrl: ctrl}
90+
mock.recorder = &GoMockRequesterMockRecorder{mock}
91+
return mock
92+
}
93+
94+
// EXPECT returns an object that allows the caller to indicate expected use.
95+
func (m *GoMockRequester) EXPECT() *GoMockRequesterMockRecorder {
96+
return m.recorder
97+
}
98+
99+
// Get mocks base method.
100+
func (m *GoMockRequester) Get(path string) (string, error) {
101+
// ...
102+
}
103+
104+
// Get indicates an expected call of Get.
105+
func (mr *GoMockRequesterMockRecorder) Get(path any) *GoMockRequesterGetCall {
106+
// ...
107+
}
108+
109+
// GoMockRequesterGetCall wrap *gomock.Call
110+
type GoMockRequesterGetCall struct {
111+
*gomock.Call
112+
}
113+
114+
// Return rewrite *gomock.Call.Return
115+
func (c *GoMockRequesterGetCall) Return(s string, err error) *GoMockRequesterGetCall {
116+
c.Call = c.Call.Return(s, err)
117+
return c
118+
}
119+
120+
// Do rewrite *gomock.Call.Do
121+
func (c *GoMockRequesterGetCall) Do(f func(string) (string, error)) *GoMockRequesterGetCall {
122+
c.Call = c.Call.Do(f)
123+
return c
124+
}
125+
126+
// DoAndReturn rewrite *gomock.Call.DoAndReturn
127+
func (c *GoMockRequesterGetCall) DoAndReturn(f func(string) (string, error)) *GoMockRequesterGetCall {
128+
c.Call = c.Call.DoAndReturn(f)
129+
return c
130+
}
131+
132+
```
133+
134+
135+
## `template-data`
136+
137+
`gomock` accepts the following `#!yaml template-data:` keys:
138+
139+
| key | type | description |
140+
|-----|------|-------------|
141+
| `boilerplate-file` | `#!yaml string` | 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. |
142+
| `mock-build-tags` | `#!yaml string` | Set the build tags of the generated mocks. Read more about the [format](https://pkg.go.dev/cmd/go#hdr-Build_constraints). |
143+
| `no-source-comment` | `#!yaml bool` | Disable writing the original package and interface names in a comment. |
144+
| `no-pkg-comment` | `#!yaml bool` | Disable writing a package documentation comment (godoc). |
145+
| `typed` | `#!yaml bool` | Generate type-safe 'Return', 'Do', 'DoAndReturn' functions. |
146+
147+
148+
### Schema
149+
150+
```json
151+
--8<-- "internal/mock_gomock.templ.schema.json"
152+
```

docs/template/index.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ Mockery provides a few embedded templates you can render, or you can use a URL t
1717

1818
Mocks generated using this template allow you to define precise functions to be run.
1919

20+
### [`#!yaml template: "gomock"`](gomock.md#description)
21+
22+
[`gomock`](gomock.md#description){ data-preview } templates replicate the mocks generated by `mockgen` from the project at https://github.com/uber-go/mock.
23+
2024
### `#!yaml template: "file://"`
2125

2226
You may also provide mockery a path to your own file using the `file://` protocol specifier. The string after `file://` will be the relative or absolute path of your template.
@@ -25,6 +29,7 @@ The templates are rendered with the data as shown in the [section below](#templa
2529

2630
You can see examples of how the mockery project utilizes the template system to generate the different mock styles:
2731

32+
- [`gomock.templ`](https://github.com/vektra/mockery/blob/v3/internal/mock_gomock.templ)
2833
- [`matryer.templ`](https://github.com/vektra/mockery/blob/v3/internal/mock_matryer.templ)
2934
- [`testify.templ`](https://github.com/vektra/mockery/blob/v3/internal/mock_testify.templ)
3035

docs/template/matryer.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ title: matryer
5353
```go
5454
// Code generated by mockery; DO NOT EDIT.
5555
// github.com/vektra/mockery
56+
// template: matryer
5657

5758
package test
5859

docs/template/testify.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ section below shows what will be rendered for the given interface.
5959
```go
6060
// Code generated by mockery; DO NOT EDIT.
6161
// github.com/vektra/mockery
62+
// template: testify
6263

6364
package test
6465

internal/cmd/mockery.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,12 @@ func (r *RootApp) Run() error {
326326
return err
327327
}
328328
fileLog.Info().Msg("Executing template")
329-
templateBytes, err := generator.Generate(fileCtx, interfacesInFile.interfaces)
329+
templateBytes, err := generator.Generate(
330+
fileCtx,
331+
interfacesInFile.interfaces,
332+
interfacesInFile.srcPkg.Name,
333+
interfacesInFile.srcPkg.PkgPath,
334+
)
330335
if err != nil {
331336
return err
332337
}

internal/fixtures/empty_return/mocks_gomock_empty_return_test.go

Lines changed: 110 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)