您应该能够通过几个更改来实现所需的功能.首先,让我介绍代码,然后我将向您介绍所有相关的更改.
main.go
file
package main
type MyInterface interface {
Foo() error
Bar() error
}
type MyStruct struct {
DS MyInterface
}
// here you've to depend upon an interface and return a pointer to a struct
func NewMyStruct(ds MyInterface) *MyStruct {
return &MyStruct{
DS: ds,
}
}
func (m *MyStruct) Foo() error {
// do something
m.DS.Bar()
// do something else
return nil
}
func (m *MyStruct) Bar() error {
// do something
return nil
}
func main() {}
在这里,我更改了几项内容,以便能够成功地模拟我们的依赖项.让我扼要地回顾一下:
MyStruct
具有类型MyInterface
的依赖项
- 函数
NewMyStruct
接受该接口作为参数,并返回指向MyStruct
struct 的指针
- 在
Foo
方法中,我们将依赖指针接收器类型实例的DS
字段
现在,让我们切换到测试文件.
main_test.go
file
package main
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
// 1. declare mock
type myStructMock struct {
mock.Mock
}
// 2. implement the interface
func (m *myStructMock) Foo() error {
args := m.Called()
return args.Error(0)
}
func (m *myStructMock) Bar() error {
args := m.Called()
return args.Error(0)
}
func TestFoo(t *testing.T) {
// 3. instantiate/setup mock
myStructMock := new(myStructMock)
myStructMock.On("Bar").Return(nil).Times(1)
sut := NewMyStruct(myStructMock)
err := sut.Foo()
// 4. check that all expectations were met on the mock
assert.Nil(t, err)
assert.True(t, myStructMock.AssertExpectations(t))
}
在这里,我发现最好在代码中添加注释,为您提供所发生的事情的时间顺序.其 idea 是,测试的真实系统(例如,sut
变量)依赖于模拟而不是实际实现.多亏了方法Times
,我们才能确保调用Bar
方法一次.
I always used this approach when it comes to testing production code and I find it pretty flexible and amazing!
Let me know if this helps you or if you still need something else, thanks!