初始化循环Golang

时间:2018-08-03 07:29:17

标签: unit-testing go mocking testify

嗨,我正在尝试使我的功能单元可测试。建议之一是将函数分配给变量,并使其可全局访问。我只是这样做了,但是现在我遇到了一个初始化循环,下面是我的代码

////////////////////////
// main.go
////////////////////////

func DownloadFile(filename string) {
    // Initialized request variable here
    // ... doing initialization
    // End of initialization

    res = ProcessDownload(request)

    if res == 401 {
       return doRetry(filename)
    }

    // some code here
    return downloadFile(filename)
}

func DoRetry(filename string) {
    // Doing some database insert/updating
   return downloadFile(string)
}

在我的另一个文件中,我将此函数分配给变量

//////////////////////
// global.go
//////////////////////

var downloadFile = DownloadFile
var doRetry = DoRetry

我在global.go中这样做的原因是使 DoRetry DownloadFile 单元可测试。通过这种方法,我可以 MOCK ,而无需创建界面。由于这只是一个独立的函数,因此不必位于某个类中。其余所有变量都可以,但是当涉及到执行递归行为的函数时,我得到以下错误

./global.go:22:5: initialization loop:
/go/src/project/global.go:22:5 downloadFile refers to
/go/src/project/process.go:403:99 DownloadFile refers to
/go/src/project/global.go:23:5 doRetry refers to
/go/src/project/process.go:394:89 DoRetry refers to
/go/src/project/global.go:22:5 downloadFile
FAIL    project [build failed]

我知道这可能在here中是重复的,但是我看不到这里的解决方案如何解决我的问题。

请帮助我。谢谢 我在此链接中了解了关于模拟函数的信息

Mock functions in Go

https://husobee.github.io/golang/testing/unit-test/2015/06/08/golang-unit-testing.html

1 个答案:

答案 0 :(得分:1)

解决方案是在声明downloadFiledoRetry函数变量时不分配值,而是将初始化推迟到包init()函数中,如下所示:

var downloadFile func(string) //= DownloadFile
var doRetry func(string)      //= DoRetry

func init() {
    downloadFile = DownloadFile
    doRetry = DoRetry
}

这样,变量首先将使用nil(函数类型的值为零)进行初始化,这意味着它们不依赖于DownloadFile()DoRetry()函数以及稍后(当包init()函数运行时),该函数会将函数值分配给变量,因此不会发生初始化循环。