Ste*_* P. 9 monkeypatching mocking go
我明白,如果代码的结构使得它被编程为接口,那么模拟它是微不足道的; 但是,我正在使用一个我无法改变的代码库(这不是我的代码库),事实并非如此.
这个代码库是高度互联的,没有任何东西被编程到接口,只有结构,所以没有依赖注入.
结构本身只包含其他结构,所以我也不能这样做.我不相信我可以对方法做任何事情,并且存在的少数函数不是变量,所以我不知道将它们交换掉.继承在golang中不是一件事,所以这也是不行的.
在像python这样的脚本语言中,我们可以在运行时修改对象,也就是猴子补丁.在golang中我能做些什么吗?试图找出一些方法来测试/基准测试而不触及底层代码.
当遇到这种情况时,我的方法是使用自己的接口作为包装器,从而可以在测试中进行模拟。例如。
type MyInterface interface {
DoSomething(i int) error
DoSomethingElse() ([]int, error)
}
type Concrete struct {
client *somepackage.Client
}
func (c *Concrete) DoSomething(i int) error {
return c.client.DoSomething(i)
}
func (c *Concrete) DoSomethingElse() ([]int, error) {
return c.client.DoSomethingElse()
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以以与模拟somepackage.Client接口相同的方式模拟混凝土。
正如@elithrar在下面的注释中所指出的那样,您可以嵌入要模拟的类型,因此只需要添加需要模拟的方法即可。例如:
type Concrete struct {
*somepackage.Client
}
Run Code Online (Sandbox Code Playgroud)
这样做后,DoSomethingNotNeedingMocking可以直接调用其他方法,Concrete而不必将其添加到接口中或将其模拟出来。