Можно ли получить текущий корень структуры пакета в виде строки в тесте golang?
Я пишу служебную функцию для своих модульных тестов, которая используется модульными тестами в нескольких пакетах. Эта служебная функция должна читать определенный файл (всегда один и тот же файл). Вот три решения, которые не работают, чтобы объяснить, что я ищу и почему.
-
Hardcode - абсолютный путь. Это не удается, потому что другой пользователь, который пытается протестировать проект, может иметь другой префикс на абсолютном пути.
-
Hardcode относительный путь от пути файла, который определяет функцию утилиты. Это терпит неудачу, потому что пакеты, которые импортируют и используют эту функцию, не обязательно находятся на одном уровне иерархии файлов, как файл, который определяет функцию утилиты, а относительные пути интерпретируются относительно импортера, а не импортированы.
-
Передайте относительный путь к файлу от каждого вызывающего абонента относительно пакета вызывающего абонента. Это действительно работает, но кажется очень многословным, потому что теперь каждый вызывающий объект должен быть изменен для передачи одного файла.
Я вижу четвертое решение, в котором я могу жестко указать путь в функции утилиты, который относится к корневому каталогу пакета верхнего уровня. Тем не менее, я не смог найти способ получить корневой каталог в коде, хотя я подозреваю, что есть один, потому что импорт может быть разрешен из корня.
Таким образом, как я могу получить искомый корневой каталог?
Я просмотрел различные документы Go, но пока не нашел решения. Я также видел этот вопрос, но решение там эквивалентно # 3 выше.
Ответы
Ответ 1
Вы также можете использовать мой метод без C:
package mypackage
import (
"path/filepath"
"runtime"
"fmt"
)
var (
_, b, _, _ = runtime.Caller(0)
basepath = filepath.Dir(b)
)
func PrintMyPath() {
fmt.Println(basepath)
}
https://play.golang.org/p/ifVRIq7Tx0
Ответ 2
Основываясь на ответе Алексея answer by Oleksiy, вы можете создать в своем проекте подпакет под названием ./internal/projectpath/projectpath.go
и вставить следующее:
package projectpath
import (
"path/filepath"
"runtime"
)
var (
_, b, _, _ = runtime.Caller(0)
// Root folder of this project
Root = filepath.Join(filepath.Dir(b), "../..")
)
Затем вы можете использовать projectpath.Root
в любом другом пакете, чтобы иметь корневую папку вашего проекта.
Ответ 3
Да, поиск пути к папке возможен:
pathfind.go:
package main
/*
const char* GetMyPathFILE = __FILE__;
*/
import "C"
import "path/filepath"
var basepath = ""
//GetMyPath Returns the absolute directory of this(pathfind.go) file
func GetMyPath() string {
if basepath == "" {
g := C.GoString(C.GetMyPathFILE)
basepath = filepath.Dir(g)
}
return basepath
}
Все, что вам нужно сделать, это скопировать этот файл в ваш проект. Имейте в виду, что это касается пути к файлу, а не вызывающего, поэтому вам нужно скопировать функцию/файл в каждый проект, в котором вам нужна функция. Кроме того, если вы помещаете это в файл с другим кодом, обязательно соблюдайте CGO
правила импорта.