是否有可能在golang测试中将当前的包结构根作为字符串?

时间:2015-08-07 08:46:45

标签: go

我正在为单元测试编写实用程序函数,单元测试在多个包中使用。此实用程序函数必须读取特定文件(始终是同一文件)。这里有三个不起作用的解决方案,用于解释我在寻找什么以及为什么。

  1. 硬编码绝对路径。这失败了,因为尝试测试项目的另一个用户在绝对路径上可能有不同的前缀。

  2. 从定义效用函数的文件路径硬编码相对路径。这会失败,因为导入和使用此函数的包不一定与文件层次结构的级别与定义实用程序函数的文件相同,并且相对路径是相对于导入程序而不是导入的来解释的。

  3. 从每个调用者传递相对于调用者包的文件的相对路径。这实际上有效,但似乎非常冗长,因为现在必须更改每个调用者以传递一个文件。

  4. 我看到第四个解决方案,我可以在实用程序函数中硬编码一个相对于顶级包根目录的路径。但是,我还没有找到一种方法来获取代码中的根目录,虽然我怀疑有一个,因为可以从根解析导入。

    因此,我如何获得广受欢迎的根目录?

    我查看了各种Go文档,但到目前为止找不到解决方案。我也见过this question但是那里的解决方案相当于上面的#3。

5 个答案:

答案 0 :(得分:35)

您也可以在没有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

答案 1 :(得分:2)

转到目录:

// from Executable Directory
ex, _ := os.Executable()
fmt.Println("Executable DIR:", filepath.Dir(ex))

// Current working directory
dir, _ := os.Getwd()
fmt.Println("CWD:", dir)

// Relative on runtime DIR:
_, b, _, _ := runtime.Caller(0)
d1 := path.Join(path.Dir(b))
fmt.Println("Relative", d1)

答案 2 :(得分:1)

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 :(得分:1)

返回应用程序的根目录

import (
    "path"
    "path/filepath"
    "runtime"
)  

func RootDir() string {
    _, b, _, _ := runtime.Caller(0)
    d := path.Join(path.Dir(b))
    return filepath.Dir(d)
}

答案 4 :(得分:-1)

是,可以查找包路径:

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
}

您所要做的就是将此文件复制到您的项目中。请记住,这会提供文件的路径,而不是调用者,因此您必须将函数/文件复制到您需要该函数的每个项目中。此外,如果您将此文件与其他代码放在一起,请务必遵守{ {1}}的导入规则。