Golang测试中资源文件路径错误问题

Golang测试中资源文件路径错误问题 我有一个关于测试中资源文件路径的问题。我有一个HTTP服务,它使用JSON文件的路径来提供RESTful微服务,并且运行正常。

如果我编写测试来测试处理程序,测试却找不到这些文件。我对Go还比较陌生,是不是漏掉了什么明显的东西?

如果我不用文件而是直接构造内容,测试就能通过。

但是使用listen和serve时,它能正常找到资源文件。如果我重命名这些文件,服务就找不到文件了,这符合预期。

4 回复

很棒的网站

更多关于Golang测试中资源文件路径错误问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


让我们看一些示例代码

与此同时,可以参考Dave Cheney的博客来了解这个问题——这始终是一个很好的资源。

抱歉,我弄明白了;只是还没来得及更新。

不要传递相对路径: “report-api/data/assets/file.JSON”

// 这对服务和我的测试都有效
wd, _ := os.Getwd()
for !strings.HasSuffix(wd, "report-api") {
    wd = filepath.Dir(wd)
}

在Go测试中,资源文件路径问题通常是由于工作目录不同导致的。当直接运行程序时,工作目录通常是项目根目录,而运行测试时,工作目录可能是测试文件所在目录。以下是解决方案:

1. 使用绝对路径或相对路径处理

// 获取当前文件所在目录
import (
    "os"
    "path/filepath"
    "runtime"
)

func getResourcePath(filename string) string {
    _, currentFile, _, _ := runtime.Caller(0)
    baseDir := filepath.Dir(currentFile)
    return filepath.Join(baseDir, "resources", filename)
}

// 在测试中使用
func TestHandler(t *testing.T) {
    jsonPath := getResourcePath("data.json")
    // 使用jsonPath读取文件
}

2. 使用embed包(Go 1.16+)

import "embed"

//go:embed resources/*.json
var resources embed.FS

func TestHandlerWithEmbed(t *testing.T) {
    data, err := resources.ReadFile("resources/data.json")
    if err != nil {
        t.Fatal(err)
    }
    // 使用data进行测试
}

3. 使用测试初始化设置工作目录

import (
    "os"
    "path/filepath"
    "testing"
)

func TestMain(m *testing.M) {
    // 切换到项目根目录
    os.Chdir("../..")
    code := m.Run()
    os.Exit(code)
}

func TestHandler(t *testing.T) {
    // 现在相对路径会基于项目根目录
    data, err := os.ReadFile("resources/data.json")
    if err != nil {
        t.Fatal(err)
    }
}

4. 环境变量控制路径

func getResourcePath() string {
    if testMode := os.Getenv("TEST_MODE"); testMode == "true" {
        return "./test_resources/data.json"
    }
    return "./resources/data.json"
}

5. 完整示例

package main

import (
    "io/ioutil"
    "path/filepath"
    "runtime"
    "testing"
)

func getTestResource(filename string) ([]byte, error) {
    _, currentFile, _, _ := runtime.Caller(0)
    baseDir := filepath.Dir(currentFile)
    resourcePath := filepath.Join(baseDir, "..", "resources", filename)
    return ioutil.ReadFile(resourcePath)
}

func TestMyHandler(t *testing.T) {
    data, err := getTestResource("config.json")
    if err != nil {
        t.Fatalf("Failed to read resource: %v", err)
    }
    
    // 使用data进行测试
    t.Logf("Resource size: %d bytes", len(data))
}

最推荐使用embed包(如果使用Go 1.16+)或runtime.Caller()方法,这两种方式都能确保在测试和运行时都能正确找到资源文件。

回到顶部