Skip to content

Commit

Permalink
Add support for gomock (#235)
Browse files Browse the repository at this point in the history
  • Loading branch information
Hardik Gajjar authored Feb 17, 2023
1 parent 59a842c commit 68e66ef
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 0 deletions.
2 changes: 2 additions & 0 deletions application/skeleton/main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:generate sh tools/scripts/mockgen.sh

package main

import (
Expand Down
13 changes: 13 additions & 0 deletions application/skeleton/test/example.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package test

type Example interface {
HelloWorld() string
}

type test struct {
ex Example
}

func (t test) Run() string {
return t.ex.HelloWorld()
}
17 changes: 17 additions & 0 deletions application/skeleton/test/example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package test

import (
"github.com/golang/mock/gomock"
"testing"
)

func TestTest_Run(t *testing.T) {
ctrl := gomock.NewController(t)
ex := NewMockExample(ctrl)
ex.EXPECT().HelloWorld().Times(1).Return("HelloWorld!")

tst := test{ex: ex}
if output := tst.Run(); output != "HelloWorld!" {
t.Errorf("expected Run() function to return 'HelloWorld!', got '%s'", output)
}
}
8 changes: 8 additions & 0 deletions application/skeleton/tools.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//go:build tools
// +build tools

package tools

import (
_ "github.com/golang/mock/mockgen"
)
23 changes: 23 additions & 0 deletions application/skeleton/tools/scripts/mockgen.sh.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/sh

{% apply spaceless %}
{% for path in @('app.mockgen.paths') %}
{% if @('app.mockgen.mode') == "source" %}

{% set pathParts = path.source|split('/') %}
{% set package = path.package | default(pathParts[pathParts|length-2]) %}
{% set destination = path.destination | default(path.source|trim('.go', 'right') ~ '_mocks.go') %}

test {{ destination }} -nt {{ path.source }} || go run github.com/golang/mock/mockgen -source={{ path.source }} -package={{ package }} -destination={{ destination }}

{% elseif @('app.mockgen.mode') == "reflect" %}

{% set pathParts = path.import|split('/') %}
{% set package = path.package | default(pathParts|last) %}
{% set destination = path.destination | default(pathParts|slice(1)|join('/') ~ '/mocks.go') %}

go run github.com/golang/mock/mockgen -package={{ package }} -destination={{ destination }} {{ path.import }} {{ path.symbols }}

{% endif %}
{% endfor %}
{% endapply %}
55 changes: 55 additions & 0 deletions docs/how-to-guides/use-gomock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# How to use gomock

[gomock] is a mocking library for GoLang. It works by generating the mocks for the interfaces you have defined in your
source code. The Go Harness comes with this library pre-installed and enabled. However, you would need to define the
source files for which you want to generate the mocks.

## Defining mocks

You can define the source paths for the mock generation in `workspace.yml`. By default, the harness comes with an example
test under `test` directory, and the mock path is defined for it too. Feel free to remove it and override the `app.mockgen`
attribute as per your requirement.
The `app.mockgen` attribute can contain following possible values:
```yaml
attributes:
app:
mockgen:
mode: source
paths:
- source: "./test/example.go"
package: "test"
destination: "./test/example_mocks.go"
mode: reflect
paths:
- import: "ci-go-sample/test"
symbols: "Example"
package: "test"
destination: "./test/example_mocks.go"
```
- `mode` defines the mockgen operation mode. There are two modes possible, `source` and `reflect`. For more information,
check [mockgen modes]. You can only use one of them.
- Depending on the mode you have selected, you would need to provide the paths:
- `source` mode: in this mode, the only required attribute is `paths.source`, which contains the relative path of the
source file which contains the interface(s) for which you want to generate the mock(s).
- `reflect` mode: in this mode, you need to provide `paths.import` and `paths.symbols`. The `paths.import` contains the path
of the package from which you want to generate the mock(s), and `paths.symbols` contains a comma-separated list of
interface names from that package for which the mocks would be generated.
- The `paths.package` and `paths.destination` attributes are optional in both modes. If you don't pass them, they will be auto-inferred.

## Commands

### `ws install --step prepare`

After modifying the `app.mockgen` attribute, you need to run this command. It will regenerate the `tools/scripts/mockgen.sh` script.

### `ws go generate`

Runs `go generate` command, which will internally execute `tools/scripts/mockgen.sh` script to regenerate mocks.

## Conditional generation

The `source` mode supports a way to conditionally regenerate the mock types only if the relevant source code has changed.
It compares the modification time of mock file with its relevant source file to detect.

[gomock]: https://github.com/golang/mock
[mockgen modes]: https://github.com/golang/mock#running-mockgen
4 changes: 4 additions & 0 deletions harness/attributes/common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ attributes.default:
additional_binaries: []
packages: []
copy_files: []
mockgen:
mode: source
paths:
- source: "./test/example.go"

domain: my127.site
hostname: = @('namespace') ~ '.' ~ @('domain')
Expand Down
1 change: 1 addition & 0 deletions harness/config/confd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ confd('harness:/'):
- { src: application/overlay/Jenkinsfile }
- { src: application/skeleton/README.md }
- { src: application/skeleton/.gitignore }
- { src: application/skeleton/tools/scripts/mockgen.sh, dst: workspace:/tools/scripts/mockgen.sh }
- { src: docker/image/app/Dockerfile }
- { src: docker/image/app/root/lib/task/gocyclo.sh }
- { src: docker/image/app/root/lib/task/gosec.sh }
Expand Down
2 changes: 2 additions & 0 deletions test
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ function test()
fi

ws helm kubeval qa
ws go generate
ws go test

ws disable
ws enable
Expand Down

0 comments on commit 68e66ef

Please sign in to comment.