Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix broken git history #553

Merged
merged 14 commits into from
Feb 21, 2023
436 changes: 4 additions & 432 deletions README.md

Large diffs are not rendered by default.

101 changes: 101 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
Changelog
=========

This changelog describes major feature additions. Please view the `releases` page for more details on commits and minor changes.

mockery
-------

### [`v2.20.0`](https://github.com/vektra/mockery/pull/538): Improved Return Value Functions

Return value functions that return an entire method's return value signature can now be provided.

```go
proxyMock := mocks.NewProxy(t)
proxyMock.On("passthrough", mock.AnythingOfType("context.Context"), mock.AnythingOfType("string")).
Return(
func(ctx context.Context, s string) (string, error) {
return s, nil
}
)
```

You may still use the old way where one function is provided for each return value:

```go
proxyMock := mocks.NewProxy(t)
proxyMock.On("passthrough", mock.AnythingOfType("context.Context"), mock.AnythingOfType("string")).
Return(
func(ctx context.Context, s string) string {
return s
},
func(ctx context.Context, s string) error {
return nil
},
)
```

### [`2.19.0`](https://github.com/vektra/mockery/releases/tag/v2.19.0): `inpackage-suffix` option

When `inpackage-suffix` is set to `True`, mock files are suffixed with `_mock` instead of being prefixed with `mock_` for InPackage mocks


### [`v2.16.0`](https://github.com/vektra/mockery/pull/527): Config Search Path

Mockery will iteratively search every directory from the current working directory up to the root path for a `.mockery.yaml` file, if one is not explicitly provided.

### [`v2.13.0`](https://github.com/vektra/mockery/pull/456): Generics support

Mocks are now capable of supporting Golang generics.

### [`v2.11.0`](https://github.com/vektra/mockery/pull/406): Mock constructors

Mockery v2.11 introduces constructors for all mocks. This makes instantiation and mock registration a bit easier and
less error-prone (you won't have to worry about forgetting the `AssertExpectations` method call anymore).

Before v2.11:
```go
factory := &mocks.Factory{}
factory.Test(t) // so that mock does not panic when a method is unexpected
defer factory.AssertExpectations(t)
```

After v2.11:
```go
factory := mocks.NewFactory(t)
```

The constructor sets up common functionalities automatically
- The `AssertExpectations` method is registered to be called at the end of the tests via `t.Cleanup()` method.
- The testing.TB interface is registered on the `mock.Mock` so that tests don't panic when a call on the mock is unexpected.

### [`v2.10.0`](https://github.com/vektra/mockery/pull/396): Expecter Structs

Mockery now supports an "expecter" struct, which allows your tests to use type-safe methods to generate call expectations. When enabled through the `with-expecter: True` mockery configuration, you can enter into the expecter interface by simply calling `.EXPECT()` on your mock object.

For example, given an interface such as
```go
type Requester interface {
Get(path string) (string, error)
}
```

You can use the type-safe expecter interface as such:
```go
requesterMock := mocks.NewRequester(t)
requesterMock.EXPECT().Get("some path").Return("result", nil)
requesterMock.EXPECT().
Get(mock.Anything).
Run(func(path string) { fmt.Println(path, "was called") }).
// Can still use return functions by getting the embedded mock.Call
Call.Return(func(path string) string { return "result for " + path }, nil)
```

### [`v2.0.0`](https://github.com/vektra/mockery/releases/tag/v2.0.0): Major Update

This is the first major update of mockery. Version 2 brings a handful of improvements to mockery:

- Structured and pretty console logging
- CLI now switches over to sp13/cobra
- Use of viper configuration parsing. You can now use a .mockery.yaml config file in your repository
- Various CI fixes and improvements
49 changes: 49 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
Configuration
==============

mockery uses [spf13/viper](https://github.com/spf13/viper) under the hood for its configuration parsing. It is bound to three different configuration sources, in order of decreasing precedence:

1. Command line
2. Environment variables
3. Configuration file

If a parameter is named `with-expecter` and we want a value of `True`, then these are the formats for each source:

| source | value |
|--------|-------|
| command line | `--with-expecter=true` |
| Environment variable | `MOCKERY_WITH_EXPECTER=True` |
| yaml | `with-expecter: True` |

Recommended Basic Config
-------------------------

Copy the recommended basic configuration to a file called `.mockery.yaml` at the top-level of your repo:

```yaml title=".mockery.yaml"
inpackage: True
testonly: True
with-expecter: True
keeptree: False
```

mockery will search upwards from your current-working-directory up to the root path, so the same configuration should be able to follow you within your project.

Parameter Descriptions
-----------------------

| name | description |
|------|-------------|
| `name` | The `name` option takes either the name or matching regular expression of the interface to generate mock(s) for. |
| `all` | It's common for a big package to have a lot of interfaces, so mockery provides `all`. This option will tell mockery to scan all files under the directory named by `--dir` ("." by default) and generates mocks for any interfaces it finds. This option implies `recursive: True`. |
| `recursive` | Use the `recursive` option to search subdirectories for the interface(s). This option is only compatible with `name`. The `all` option implies `recursive: True`. |
| `output` | mockery always generates files with the package `mocks` to keep things clean and simple. You can control which mocks directory is used by using `output`, which defaults to `./mocks`. |
|`outpkg`| Use `outpkg` to specify the package name of the generated mocks.|
| `inpackage` and `keeptree` | For some complex repositories, there could be multiple interfaces with the same name but in different packages. In that case, `inpackage` allows generating the mocked interfaces directly in the package that it mocks. In the case you don't want to generate the mocks into the package but want to keep a similar structure, use the option `keeptree`. |
| `filename` | Use the `filename` and `structname` to override the default generated file and struct name. These options are only compatible with non-regular expressions in `name`, where only one mock is generated. |
| `case` | mockery generates files using the casing of the original interface name. This can be modified by specifying `case: underscore` to format the generated file name using underscore casing. |
| `print` | Use `print: True` to have the resulting code printed out instead of written to disk. |
| `exported` | Use `exported: True` to generate public mocks for private interfaces. |
| `with-expecter` | Use `with-expecter: True` to generate `EXPECT()` methods for your mocks. This is the preferred way to setup your mocks. |
| `testonly` | Prepend every mock file with `_test.go`. This is useful in cases where you are generating mocks `inpackage` but don't want the mocks to be visible to code outside of tests. |
| `inpackage-suffix` | When `inpackage-suffix` is set to `True`, mock files are suffixed with `_mock` instead of being prefixed with `mock_` for InPackage mocks |
121 changes: 121 additions & 0 deletions docs/examples.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
Examples
========

### Simple case

Given this interface:

```go title="string.go"
package example_project

//go:generate --name Stringer
type Stringer interface {
String() string
}
```

Run: `go generate` (using the recommended config) and the the file `mock_Stringer_test.go` will be generated. You can now use this mock to create assertions and expectations.

```go title="string_test.go"
package example_project

import (
"testing"

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

func Foo(s Stringer) string {
return s.String()
}

func TestString(t *testing.T) {
mockStringer := NewMockStringer(t)
mockStringer.EXPECT().String().Return("mockery")
assert.Equal(t, "mockery", Foo(mockStringer))
}
```

Note that in combination with using the mock's constructor and the `.EXPECT()` directives, your test will automatically fail if the expected call is not made.

### Function type case

Given this is in `send.go`

```go
package test

type SendFunc func(data string) (int, error)
```

Run: `mockery --name=SendFunc` and the following will be output:

```go title="mock_SendFunc_test.go"
package mocks

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

testing "testing"
)

type SendFunc struct {
mock.Mock
}

func (_m *SendFunc) Execute(data string) (int, error) {
ret := _m.Called(data)

var r0 int
if rf, ok := ret.Get(0).(func(string) int); ok {
r0 = rf(data)
} else {
r0 = ret.Get(0).(int)
}

var r1 error
if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(data)
} else {
r1 = ret.Error(1)
}

return r0, r1
}

// NewSendFunc creates a new instance of SendFunc. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
func NewSendFunc(t testing.TB) *SendFunc {
mock := &SendFunc{}
mock.Mock.Test(t)

t.Cleanup(func() { mock.AssertExpectations(t) })

return mock
}
```

### Return Value Provider Functions

If your tests need access to the arguments to calculate the return values,
set the return value to a function that takes the method's arguments as its own
arguments and returns the return value. For example, given this interface:

```go
package test

type Proxy interface {
passthrough(ctx context.Context, s string) string
}
```

The argument can be passed through as the return value:

```go
import . "github.com/stretchr/testify/mock"

proxyMock := mocks.NewProxy(t)
proxyMock.On("passthrough", mock.AnythingOfType("context.Context"), mock.AnythingOfType("string")).
Return(func(ctx context.Context, s string) string {
return s
})
```
70 changes: 70 additions & 0 deletions docs/features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
Features
========

Expecter Structs
----------------

|config|`with-expecter: True`|
|-|-|

Mockery now supports an "expecter" struct, which allows your tests to use type-safe methods to generate call expectations. When enabled through the `with-expecter: True` mockery configuration, you can enter into the expecter interface by simply calling `.EXPECT()` on your mock object.

For example, given an interface such as
```go
type Requester interface {
Get(path string) (string, error)
}
```

You can use the expecter interface as such:
```go
requesterMock := mocks.NewRequester(t)
requesterMock.EXPECT().Get("some path").Return("result", nil)
requesterMock.EXPECT().
Get(mock.Anything).
Run(func(path string) { fmt.Println(path, "was called") }).
// Can still use return functions by getting the embedded mock.Call
Call.Return(func(path string) string { return "result for " + path }, nil)
```

Note that the types of the arguments on the `EXPECT` methods are `interface{}`, not the actual type of your interface. The reason for this is that you may want to pass `mock.Any` as an argument, which means that the argument you pass may be an arbitrary type. The types are still provided in the expecter method docstrings.


Return Value Providers
----------------------

Return Value Providers can be used one of two ways. You may either define a single function with the exact same signature (number and type of input and return parameters) and pass that as a single value to `Return`, or you may pass multiple values to `Return` (one for each return parameter of the mocked function.) If you are using the second form, for each of the return values of the mocked function, `Return` needs a function which takes the same arguments as the mocked function, and returns one of the return values. For example, if the return argument signature of `passthrough` in the above example was instead `(string, error)` in the interface, `Return` would also need a second function argument to define the error value:

```go
type Proxy interface {
passthrough(ctx context.Context, s string) (string, error)
}
```

First form:

```go
proxyMock := mocks.NewProxy(t)
proxyMock.On("passthrough", mock.AnythingOfType("context.Context"), mock.AnythingOfType("string")).
Return(
func(ctx context.Context, s string) (string, error) {
return s, nil
}
)
```


Second form:

```go
proxyMock := mocks.NewProxy(t)
proxyMock.On("passthrough", mock.AnythingOfType("context.Context"), mock.AnythingOfType("string")).
Return(
func(ctx context.Context, s string) string {
return s
},
func(ctx context.Context, s string) error {
return nil
},
)
```
Loading