drhg24275 2016-07-12 05:50
浏览 34
已采纳

如何使用Go for Unit Testing指定App Engine模板的路径?

I'm using the built-in template package with Go on App Engine.

I have a handler that renders a template to the output.

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)
  }
}

When I run the local development server this works fine.

When I run the unit test to test the page, it panics and gives me the message:

panic: open templates/index.html: no such file or directory [recovered]

The unit test is as follows:

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)
}

Basically, the problem is that for the unit test, the server is unable to find the path of the template.

How do I specify the path for the template files when running the test?

  • 写回答

1条回答 默认 最新

  • dqoqnmb163241 2016-07-12 07:45
    关注

    The problem is that when you run your app e.g. with goapp serve, the current directory is the app root (where app.yaml resides). So normally you provide paths relative to app root.

    But when you run tests e.g. with goapp test, the current directory is always the folder containing the test file being run (*_test.go). If the test file is not in the app root (normally it isn't), relative paths that are correctly resolved to the app root will not work when being resolved to another folder (containing the test file).

    Here are 2 options for your problem:

    1. Change the working directory to the app root

    You may use os.Chdir() to change the working directory to your app's root folder prior to calling code that uses relative paths. You may even put this into an init() function, or call it from your test method (whichever suits you).

    Let's assume your test file is in the folder: [APP_ROOT]/my/package/some_test.go. You may set the app's root like this (2 levels up in the hierarchy):

    if err := os.Chdir("../.."); err != nil {
        panic(err)
    }
    

    Note that I would add this line in a package init function in the test file like this:

    func init() {
        if err := os.Chdir("../.."); err != nil {
            panic(err)
        }
    }
    

    Because if you have multiple test functions in the test file and you run this code multiple times, the result will not be what you want (as we specified to go up 2 levels from the current).

    2. Refactoring code

    If you want to test code that uses relative paths, you may change / refactor the code to take the base of relative path e.g. from a variable which the test may change (knowing the current directory is its containing folder) so that the original relative path will also work when running from test and being resolved to a different base path.

    For example this base path may be the empty string "" when your app is running normally (so it will mean the current folder which in this case is the app root), and when tests are running, you may set it to the app's root (absolute path) or something like "../.." to step 2 levels up in the directory hierarchy (because current directory is the containing folder of the test file).

    You can also make the base path to which relative paths are resolved against more configurable, see this question for details: how to reference a relative file from code and tests

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记