File golang测试临时目录

File golang测试临时目录,file,testing,go,File,Testing,Go,我有一个简单的函数,它将配置文件解析为JSON。我想编写一个测试,它要么使用一些示例静态配置文件并解析它们,要么在测试期间创建示例并尝试解析它们 这不是完全必要的问题,但以下是基本代码: // config.go // ...(package,imports)... // Overall settings - corresponds to main.conf type MainSettings struct { // stuff } // Load main.conf from t

我有一个简单的函数,它将配置文件解析为JSON。我想编写一个测试,它要么使用一些示例静态配置文件并解析它们,要么在测试期间创建示例并尝试解析它们

这不是完全必要的问题,但以下是基本代码:

// config.go

// ...(package,imports)...

// Overall settings - corresponds to main.conf
type MainSettings struct {
    // stuff
}

// Load main.conf from the specified file path
func LoadMainSettings(path string) (*MainSettings, error) {

    b, err := ioutil.ReadFile(path)
    if err != nil { return nil, err }

    r := &MainSettings{}
    err = json.Unmarshal(b, r)
    if err != nil { return nil, err }

    return r, nil

}
以及测试:

// config_test.go

func TestLoadMainSettings(t *testing.T) {

    // possibly generate some example config files,
    // or use static samples packaged with the source

    s, err := LoadMainSettings("conf/main.conf") // <-- what should this path be??
    if err != nil { panic(err) }

    // more sanity checking...

}
f, err := ioutil.TempFile("", "testmainconf")
if err != nil { panic(err) }
defer syscall.Unlink(f.Name())
ioutil.WriteFile(f.Name(), []byte("{...sample config data...}"), 0644)

s, err := LoadMainSettings(f.Name())

但是让LoadMain设置接受
io.Reader
而不是
字符串的另一个建议也是一个好主意

您可以使用同一软件包中的或TempFile。

为了与您使用的
ioutil.TempDir
进行比较,以下是使用
io.Reader时的情况:

// Load main.conf from the specified file path
func LoadMainSettings(src io.Reader) (*MainSettings, error) {
    b, err := ioutil.ReadAll(src)
    if err != nil { return nil, err }

    r := &MainSettings{}
    err = json.Unmarshal(b, r)
    if err != nil { return nil, err }

    return r, nil
}
具体来说,我们将参数从
path
字符串更改为
src
io.Reader
实例,并将
ioutil.ReadFile
替换为
ioutil.ReadAll

您编写的测试用例最终会稍微缩短,因为我们可以省去文件操作:

s, err := LoadMainSettings(strings.NewReader("{...sample config data...}"))

自Go版本1.15以来,标准
测试包中现在有
T.TempDir()
。报告如下:

TempDir返回测试要使用的临时目录。这个 当测试和所有操作完成时,目录将通过清理自动删除 它的子测试是完整的。对t.TempDir的每个后续调用都返回一个 唯一目录;如果目录创建失败,TempDir将终止 通过调用Fatal进行测试


您能否编写测试,使其直接使用
io.Reader
?如果是这样,那么您的测试用例就不需要依赖于文件系统,因为您的测试可以使用
strings.NewReader
在测试本身中提供适当的测试内容。嗯-这是一个有趣的想法。。。对调用者来说稍微麻烦一点,但如果不是这样的话,是的,在这种情况下就可以了。对调用者来说应该不会更麻烦。一个文件已经是一个
io.Reader
了。真-但字符串不是,但我明白你的意思。我同意这是一个好主意。为了记录在案,如果使用带有路径参数的func更方便,可以使用路径参数编写公共函数,并使用io.Reader(打开文件)从其中调用私有func。然后只测试内部函数。另一个只是一个包装器,它所做的只是“测试”编译器。酷-是的,这就是我最后要做的。对,这很有意义-为了测试。它还意味着主程序中的调用者将执行:f,err:=os.Open(“conf/main.conf”)/*检查文件打开错误*/延迟f.close();s、 错误:=LoadMain设置(f);如果配置总是从文件中读取,并且我有几种不同的类型(LoadSomeOtherSettings()、LoadYetAnotherConfig(),等等),我认为这种方法可能不是最好的方法。除非我遗漏了什么……还有一件事:我想我是在将这与我在Java方面的经验进行比较,在Java中,通常会创建一个输出目录作为JUnit测试套件执行的一部分,它通常不仅包含测试结果,而且还包含一个临时目录,测试相关的项目可以放在其中。你知道,当“干净”在构建上运行时,它将全部消失。让事情变得简单。我只是想知道在围棋中是否存在一些相应的概念,但正如我所看到的(你也指出的),可能更好的方法是以不同的方式处理这个问题。是的。临时文件也可以。您可以在诸如的包的“testdata”子目录中看到它们。所以这里没有硬性规定:有时将测试数据放在文件中是有意义的,有时将它们嵌入到测试中也是有意义的。正如在Java中一样(在Java中到处都可以看到
Java.io.InputStream
Java.io.Reader
),您会看到大多数Go代码都与通用
io.Reader
一起工作,所以我只想确保它作为解决您问题的一种方法被记录在案P