Golang猴子补丁

我知道如果 go 代码的结构使得它被编程为接口,那么模拟是微不足道的;但是,我正在使用无法更改的代码库(那不是我的),但事实并非如此。

这个代码库是高度互连的,没有任何东西被编程到接口,只有结构,所以没有依赖注入。

结构本身只包含其他结构,所以我也不能这样模拟。我不相信我可以对方法做任何事情,而且存在的少数函数不是变量,所以我不知道将它们换掉。继承在 golang 中不是一回事,所以这也是不行的。

在像 python 这样的脚本语言中,我们可以在运行时修改对象,也就是猴子补丁。我可以在 golang 中做一些类似的事情吗?试图找出某种方法来测试/基准测试而不触及底层代码。


眼眸繁星
浏览 218回答 3
3回答

米脂

当我遇到这种情况时,我的方法是使用我自己的接口作为允许在测试中进行模拟的包装器。例如。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接口一样模拟 Concrete 。正如@elithrar在下面的评论中指出的那样,您可以嵌入您想要模拟的类型,因此您只需要添加需要模拟的方法。例如:type Concrete struct {    *somepackage.Client}这样做后,DoSomethingNotNeedingMocking可以直接调用其他方法,Concrete而无需将其添加到接口/模拟出来。

慕标琳琳

Go有一个可用的猴子补丁库。它仅适用于 Intel/AMD 系统(特别针对 OSX 和 Ubuntu)。

幕布斯7119047

根据情况,您可以应用“依赖倒置原则”并利用 Go 的隐式接口。为此,您在包中定义您的需求接口以及使用情况(而不是定义您在实现它的包中提供的内容;就像您在 Java 中一样)。然后,您可以独立于依赖项来测试您的代码。具有结构依赖的典型对象:// Object that relies on a structtype ObjectUnderTestBefore struct {    db *sql.DB}func (o *ObjectUnderTestBefore) Delete() error {    o.db.Exec("DELETE FROM sometable")}应用依赖倒置原则(带隐式接口)// subset of sql.DB which defines our "requirements"type dbExec interface {    Exec(query string, args ...interface{}) (sql.Result, error)}// Same object with it's requirement defined as an local interfacetype ObjectUnderTestWithDIP struct {    // *sql.DB will implicitly implement this interface    db dbExec}func (o *ObjectUnderTestWithDIP) Delete() error {    o.db.Exec("DELETE FROM sometable")}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go