如何为已抽象复杂度的Golang函数编写测试?
Go中如何测试依赖外部函数的代码且不修改调用方逻辑
我正在尝试为一个调用外部函数的简单Go函数编写测试。此前查过相关问题,但没找到能让调用代码无需了解被调用函数内部逻辑即可完成测试的方案。
举个例子,我有一个finder.go文件:
package finder import ( "errors" "os/exec" ) // 如此编写的话,finder.Get() 只需知晓如何判断哪个程序已安装 func Get() (string, error) { pth, err := exec.LookPath("thing1") if err == nil { return pth, nil } if !errors.Is(err, exec.ErrNotFound) { return "", err } pth, err = exec.LookPath("thing2") if err == nil { return pth, nil } return "", errors.New("you must have either thing1 or thing2 installed for this to work") }
另一个包的main.go调用该函数:
package main import ( "fmt" "os" "path/to/whatever/finder" ) // 调用函数无需知晓finder.Get()的内部逻辑,只需请求可用程序 func main() { path, err := finder.Get() if err != nil { fmt.Errorf("it's broken") os.Exit(1) } fmt.Println(path) }
目前找到的唯一可测试方案是修改程序:要么让main()知晓finder.Get()需要路径查找函数并传入,要么定义结构体绑定方法并注入函数——本质都是依赖注入方案的变体。
我想知道:能不能编写调用方只需知晓被调用函数返回值、无需了解内部实现的Go程序?当前代码可正常运行,但我需要为它编写测试。如果Go无法实现这点,那在这种无法抽象复杂度的情况下,该如何编写复杂软件?有没有合适的设计模式?
在Python里只需mock exec.LookPath就能实现测试:
@patch("path.to.finder.exec.LookPath") def test_get(): ...
但Go不支持猴子补丁,还有哪些可选方案?难道所有Go程序都要求调用方传入所有所需工具吗?
内容的提问来源于stack exchange,提问作者Daniel Quinn
相关产品推荐
相关产品推荐

