I'm currently unit testing a piece of code which uses an interface that contains a method with no input or output. Using testify's mock package, what is the proper way to write a mock implementation of this function?
Currently, I've written it as:
type A struct {
mock.Mock
}
func (a *A) DoSomething() {
_ = a.Called(nil)
}
Let's say you have something like this:
package foo
type Foo struct {}
func New() *Foo {
return &Foo{}
}
func (f *Foo) Called() {
fmt.Println("no in/output, does something here")
}
package bar
type Dependency interface {
Called() // the dependency you want to make sure is called
}
type Svc struct {
dep Dependency
}
func New(d Dependency) *Svc {
return &Svc{
dep: d,
}
}
func (s *Svc) Something() {
s.dep.Called()
}
Now, using mockgen as outlined in this related answer of mine we can add the following bit:
package bar
//go:generate go run github.com/golang/mock/mockgen -destination mocks/deps_mock.go -package mocks your.mod/path/to/pkg/bar Dependency
type Dependency interface {
Called() // the dependency you want to make sure is called
}
type Svc struct {
dep Dependency
}
func New(d Dependency) *Svc {
return &Svc{
dep: d,
}
}
func (s *Svc) Something() {
s.dep.Called()
}
This will generate a package under bar
(as in bar/mocks
), which contains the generated mock/fake/spy object you'll want to use in your test like this:
package bar_test
import (
"testing"
"your.mod/path/to/bar"
"your.mod/path/to/bar/mocks"
"github.com/golang/mock/gomock"
)
func TestSomething(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish() // this is when the expected calls are checked
dep := mocks.NewMockDependency(ctrl) // create the instance of the mock/spy
svc := bar.New(dep) // pass in the spy
dep.EXPECT().Called().Times(1)
svc.Something() // the test will pass if the call was made
// alternatively, you can log some output, too:
dep.EXPECT().Called().Times(1).Do(func() {
// this gets called as though it was s.Called() in your code
t.Log("The dependency was called as expected")
})
svc.Something()
}
mockgen/gomock can do a lot more than just this, read more about it here. It seems like the repo was recently archived and moved, I suspect its replacement is pretty much a drop in replacement + some new functionality though.