如何使用 Go 指定 App Engine 模板路径进行单元测试?

che*_*eze 5 google-app-engine templates unit-testing go

我在 App Engine 上使用 Go 的内置模板包。

我有一个处理程序,可以将模板渲染到输出。

templates := []string{"templates/head.html", "templates/footer.html"}

func pageIndex(w http.ResponseWriter, r *http.Request) {
  tpls := append([]string{"templates/index.html"}, templates...)
  tpl := template.Must(template.ParseFiles(tpls...))
  err := tpl.ExecuteTemplate(w, "index", map[string]string{
    "Title": "Index Page",
  })

  if err != nil {
    http.Error(w, err.Error(), http.StatusInternalServerError)
  }
}
Run Code Online (Sandbox Code Playgroud)

当我运行本地开发服务器时,效果很好。

当我运行单元测试来测试页面时,它会出现恐慌并给出消息:

恐慌:打开 templates/index.html:没有这样的文件或目录 [已恢复]

单元测试如下:

func TestPageIndex(t *testing.T) {
  inst, _ := aetest.NewInstance(nil)
  //ignoring the errors for brevity
  defer inst.Close()

  req, _ := inst.NewRequest("GET", "/", nil)
  resp := httptest.NewRecorder()
  pageIndex(resp, req)
}
Run Code Online (Sandbox Code Playgroud)

基本上,问题是对于单元测试,服务器无法找到模板的路径。

运行测试时如何指定模板文件的路径?

icz*_*cza 5

问题是,当您运行应用程序时,例如使用goapp serve,当前目录是应用程序根目录(所在的app.yaml位置)。因此,通常您提供相对于应用程序根目录的路径。

但是,当您使用 运行测试时goapp test,当前目录始终是包含正在运行的测试文件的文件夹 ( *_test.go)。如果测试文件不在应用程序根目录中(通常不是),则正确解析到应用程序根目录的相对路径在解析到另一个文件夹(包含测试文件)时将不起作用。

针对您的问题,有 2 个选项:

1. 将工作目录更改为应用程序根目录

在调用使用相对路径的代码之前,您可以os.Chdir()将工作目录更改为应用程序的根文件夹。您甚至可以将其放入init()函数中,或从测试方法中调用它(无论哪种适合您)。

我们假设您的测试文件位于文件夹中:[APP_ROOT]/my/package/some_test.go。您可以像这样设置应用程序的根目录(层次结构中的 2 级):

if err := os.Chdir("../.."); err != nil {
    panic(err)
}
Run Code Online (Sandbox Code Playgroud)

请注意,我会在测试文件的包初始化函数中添加这一行,如下所示:

func init() {
    if err := os.Chdir("../.."); err != nil {
        panic(err)
    }
}
Run Code Online (Sandbox Code Playgroud)

因为如果测试文件中有多个测试函数并且多次运行此代码,结果将不是您想要的(正如我们指定的从当前值上升 2 级)。

2.重构代码

如果您想测试使用相对路径的代码,您可以更改/重构代码以获取相对路径的基础,例如从测试可能更改的变量(知道当前目录是其包含文件夹)中获取相对路径的基础,以便原始相对路径当从测试运行并解析到不同的基本路径时也将起作用。

例如,""当您的应用程序正常运行时,此基本路径可能是空字符串(因此它将表示当前文件夹,在本例中是应用程序根目录),并且当测试运行时,您可以将其设置为应用程序的根目录(绝对路径)路径)或类似于"../.."步骤 2 的目录层次结构中的级别(因为当前目录是测试文件的包含文件夹)。

您还可以使相对路径解析的基本路径更可配置,有关详细信息,请参阅此问题:如何从代码和测试中引用相对文件