我目前正在对一段代码进行单元测试,该代码使用的接口包含没有输入或输出的方法。使用testify的mock包,编写这个函数的mock实现的正确方法是什么?
目前,我把它写成:
type A struct {
mock.Mock
}
func (a *A) DoSomething() {
_ = a.Called(nil)
}
假设你有这样的东西:
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()
}
现在,使用mockgen,如我的相关答案中所述,我们可以添加以下内容:
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()
}
这将在
bar
下生成一个包(如 bar/mocks
中所示),其中包含您要在测试中使用的生成的模拟/假/间谍对象,如下所示:
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 可以做的远不止这些,请阅读更多相关内容这里。似乎该存储库最近已存档并移动,我怀疑其替代品几乎是替代品的下降+一些新功能。