我知道,如果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() }
现在,您可以以与模拟somepackage.Client接口相同的方式模拟混凝土。
somepackage.Client
正如@elithrar在下面的注释中指出的那样,您可以嵌入要模拟的类型,因此只需要添加需要模拟的方法即可。例如:
type Concrete struct { *somepackage.Client }
当这样做时,DoSomethingNotNeedingMocking可以直接调用其他方法,Concrete而不必将其添加到接口中或将其模拟出来。
DoSomethingNotNeedingMocking
Concrete