Цикл инициализации Голанга

Привет, я пытаюсь сделать мой функциональный блок тестируемым. Одним из предложений было присвоить функцию переменной и сделать ее доступной в глобальном масштабе. Я только что сделал это, но теперь я испытываю цикл инициализации ниже мой код

////////////////////////
// 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 тестируемым. Имея в виду этот метод, я могу МОКРИТЬ функцию без создания интерфейса. Так как это всего лишь отдельная функция, и она не должна быть в определенном классе. Все остальные переменные в порядке, но когда дело доходит до функции, выполняющей рекурсивное поведение, я получаю ошибку ниже

./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]

Я знаю, что это может быть дубликатом здесь, но я не вижу, как решение здесь решает мою проблему.

Пожалуйста помоги мне с этим. Спасибо, я читал о насмешке функции в этой ссылке

Макетные функции в Go

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

1 ответ

Решение

Решение состоит в том, чтобы не назначать значения, когда вы объявляете downloadFile а также doRetry переменные функции, но "откладывают" инициализацию в пакет init() функция, как это:

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

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

Таким образом, переменные сначала будут инициализированы с nil (нулевое значение для типов функций), что означает, что они не зависят от DownloadFile() а также DoRetry() функции, а позже, когда пакет init() запускается функция, которая присваивает значения функции переменным, поэтому цикл инициализации не произойдет.

Другие вопросы по тегам