Skip to content

Commit

Permalink
Add docs/examples etc.
Browse files Browse the repository at this point in the history
  • Loading branch information
LandonTClipp committed Jan 2, 2025
1 parent f798319 commit 110ff94
Show file tree
Hide file tree
Showing 60 changed files with 6,174 additions and 10,863 deletions.
13 changes: 9 additions & 4 deletions .mockery.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,27 @@ packages:
github.com/vektra/mockery/v3/pkg/fixtures:
config:
all: True
dir: "{{.InterfaceDir}}"
filename: "mocks.go"
pkgname: "test"
mockname: "Mock{{.InterfaceName}}"
interfaces:
Requester:
RequesterArgSameAsNamedImport:
RequesterVariadic:
configs:
- mockname: RequesterVariadicOneArgument
- mockname: MockRequesterVariadicOneArgument
template-data:
unroll-variadic: False
- mockname: RequesterVariadic
- mockname: MockRequesterVariadic
template-data:
unroll-variadic: True
Expecter:
configs:
- mockname: ExpecterAndRolledVariadic
- mockname: MockExpecterAndRolledVariadic
template-data:
unroll-variadic: False
- mockname: Expecter
- mockname: MockExpecter
template-data:
unroll-variadic: True
RequesterReturnElided:
Expand Down
22 changes: 8 additions & 14 deletions .mockery_moq.yaml
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
mockname: "{{.InterfaceName}}Mock"
filename: "moq_test.go"
template: moq
dir: "mocks/moq/{{.SrcPackagePath}}"
formatter: "goimports"

packages:
github.com/vektra/mockery/v3/pkg/fixtures:
config:
include-regex: '.*'
exclude-regex: 'RequesterGenerics|UnsafeInterface|requester_unexported'
pkgname: test
template-data:
with-resets: true
skip-ensure: true
stub-impl: false
github.com/vektra/mockery/v3/pkg/fixtures:
config:
dir: "{{.InterfaceDir}}"
filename: "mocks_moq.go"
pkgname: "test"
mockname: "Moq{{.InterfaceName}}"
interfaces:
Requester:
2 changes: 1 addition & 1 deletion Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ tasks:
mocks.remove:
desc: remove all mock files
cmds:
- find . -name '*_mock.go' -o -name 'mock_*_test.go' | xargs -r rm
- find . -name '*_mock.go' -o -name 'mock_*_test.go' -o -name 'mocks.go' -o -name "mocks_moq.go" | xargs -r rm
- rm -rf mocks/

mocks.generate.mockery:
Expand Down
315 changes: 315 additions & 0 deletions docs/templates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,315 @@
Templates
=========

Mockery, in its essence, renders templates. This project provides a number of pre-curated
templates that you can select with the `#!yaml template:` config parameter.

## Template Options

### `#!yaml template: "mockery"`

Choosing this template will render a traditional "mockery-style" template. The
section below shows what will be rendered for the given interface.

=== "Interface"

```go
package test

type Requester interface {
Get(path string) (string, error)
}
```

=== "`.mockery.yml`"

```yaml
template: mockery
packages:
github.com/vektra/mockery/v3/pkg/fixtures:
config:
dir: "{{.InterfaceDir}}"
filename: "mocks.go"
pkgname: "test"
mockname: "Mock{{.InterfaceName}}"
interfaces:
Requester:
```

=== "`mocks.go`"

```go
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery

package test

import (
mock "github.com/stretchr/testify/mock"
)


// NewRequester creates a new instance of Requester. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewRequester (t interface {
mock.TestingT
Cleanup(func())
}) *Requester {
// ...
}


// Requester is an autogenerated mock type for the Requester type
type Requester struct {
mock.Mock
}

type Requester_Expecter struct {
mock *mock.Mock
}

func (_m *Requester) EXPECT() *Requester_Expecter {
// ...
}



// Get provides a mock function for the type Requester
func (_mock *Requester) Get(path string) (string, error) {
// ...
}



// Requester_Get_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Get'
type Requester_Get_Call struct {
*mock.Call
}



// Get is a helper method to define mock.On call
// - path
func (_e *Requester_Expecter) Get(path interface{}, ) *Requester_Get_Call {
// ...
}

func (_c *Requester_Get_Call) Run(run func(path string)) *Requester_Get_Call {
// ...
}

func (_c *Requester_Get_Call) Return(s string, err error) *Requester_Get_Call {
// ...
}

func (_c *Requester_Get_Call) RunAndReturn(run func(path string)(string, error)) *Requester_Get_Call {
// ...
}
```

=== "Example Usage"

```go
package test

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestRequesterMock(t *testing.T) {
m := NewMockRequester(t)
m.EXPECT().Get("foo").Return("bar", nil).Once()
retString, err := m.Get("foo")
assert.NoError(t, err)
assert.Equal(t, retString, "bar")
}
```

As you can see, this mock utilizes `github.com/stretchr/testify` under the hood and registers call expectations with testify. When the mock receives a call to `Get()`, it retrieves the expected value from testify to be returned.

This style of mock also has other interesting methods:

=== "`#!go Run()`"

Run a side effect when the argument matches.

```go
func TestRequesterMockRun(t *testing.T) {
m := NewMockRequester(t)
m.EXPECT().Get(mock.Anything).Return("", nil)
m.EXPECT().Get(mock.Anything).Run(func(path string) {
fmt.Printf("Side effect! Argument is: %s", path)
})
retString, err := m.Get("hello")
assert.NoError(t, err)
assert.Equal(t, retString, "")
}
```

=== "`#!go RunAndReturn()`"

Run a function to perform side-effects, and return the result of the function.

```go
func TestRequesterMockRunAndReturn(t *testing.T) {
m := NewMockRequester(t)
m.EXPECT().Get(mock.Anything).RunAndReturn(func(path string) (string, error) {
return path + " world", nil
})
retString, err := m.Get("hello")
assert.NoError(t, err)
assert.Equal(t, retString, "hello world")
}
```

=== "`github.com/stretchr/testify/mock.Mock`"

Because the mock embeds the testify `Mock` object, you can all any methods on that as well.

```go
func TestRequesterMockTestifyEmbed(t *testing.T) {
m := NewMockRequester(t)
m.EXPECT().Get(mock.Anything).Return("", nil).Twice()
m.Get("hello")
m.Get("world")
assert.Equal(t, len(m.Mock.Calls), 2)
}
```
#### `template-data`

| key | type | description |
|-----|------|-------------|
| `unroll-variadic` | `#!yaml bool` | If set to `#!yaml true`, will expand the variadic argument to testify using the `...` syntax. See [notes](./notes.md#variadic-arguments) for more details. |

### `#!yaml template: "moq"`

`moq` templates draw from the mocks generated from the project at https://github.com/matryer/moq. This project was folded into mockery, and thus moq-style mocks can be natively generated from within mockery.


=== "Interface"

```go
package test

type Requester interface {
Get(path string) (string, error)
}
```

=== "`.mockery.yml`"

```yaml
template: moq
packages:
github.com/vektra/mockery/v3/pkg/fixtures:
config:
dir: "{{.InterfaceDir}}"
filename: "mocks_moq.go"
pkgname: "test"
mockname: "Moq{{.InterfaceName}}"
interfaces:
Requester:
```

=== "`mocks_moq.go`"

```go
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery

package test

import (
"sync"
)

// Ensure, that MoqRequester does implement Requester.
// If this is not the case, regenerate this file with moq.
var _ Requester = &MoqRequester{}

// MoqRequester is a mock implementation of Requester.
//
// func TestSomethingThatUsesRequester(t *testing.T) {
//
// // make and configure a mocked Requester
// mockedRequester := &MoqRequester{
// GetFunc: func(path string) (string, error) {
// panic("mock out the Get method")
// },
// }
//
// // use mockedRequester in code that requires Requester
// // and then make assertions.
//
// }
type MoqRequester struct {
// GetFunc mocks the Get method.
GetFunc func(path string) (string, error)

// calls tracks calls to the methods.
calls struct {
// Get holds details about calls to the Get method.
Get []struct {
// Path is the path argument value.
Path string
}
}
lockGet sync.RWMutex
}

// Get calls GetFunc.
func (mock *MoqRequester) Get(path string) (string, error) {
// ...
}

// GetCalls gets all the calls that were made to Get.
// Check the length with:
//
// len(mockedRequester.GetCalls())
func (mock *MoqRequester) GetCalls() []struct {
Path string
} {
// ...
}

```

=== "Example Usage"

```go
func TestRequesterMoq(t *testing.T) {
m := &MoqRequester{
GetFunc: func(path string) (string, error) {
fmt.Printf("Go path: %s\n", path)
return path + "/foo", nil
},
}
result, err := m.Get("/path")
assert.NoError(t, err)
assert.Equal(t, "/path/foo", result)
}
```

Moq-style mocks are far simpler, and probably more intuitive, than mockery-style mocks. All that's needed is to define the function that will be run when the mock's method is called.

#### `template-data`

`moq` accepts the following `#!yaml template-data:` keys:

| key | type | description |
|-----|------|-------------|
| `skip-ensure` | `#!yaml bool` | Suppress mock implementation check, avoid import cycle if mocks generated outside of the tested package. |
| `stub-impl` | `#!yaml bool` | Return zero values when no mock implementation is provided, do not panic. |

### `#!yaml template: "file://`

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.


## Data Provided To Templates

!!! warning "Construction"

This section is under construction.
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ nav:
- Getting Started:
- Installation: installation.md
- Configuration: configuration.md
- Templates: templates.md
- Running: running.md
- Examples: examples.md
- Features: features.md
Expand Down
Loading

0 comments on commit 110ff94

Please sign in to comment.