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

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

报告相同问题?

悬赏问题

  • ¥17 pro*C预编译“闪回查询”报错SCN不能识别
  • ¥15 微信会员卡接入微信支付商户号收款
  • ¥15 如何获取烟草零售终端数据
  • ¥15 数学建模招标中位数问题
  • ¥15 phython路径名过长报错 不知道什么问题
  • ¥15 深度学习中模型转换该怎么实现
  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向