html/template golang面临无效内存地址错误的单元测试

huangapple go评论117阅读模式
英文:

Unit test for html/template golang facing invalid memory address error

问题

所以我有一个简单的应用程序,应该在GET请求/login/上呈现一个Html页面。当我在本地运行Web服务器时,请求工作正常,但是当我运行单元测试时似乎出现了错误。(使用go test -v来运行测试。)

  1. --- FAIL: TestLoginRequest (0.00s)
  2. panic: runtime error: invalid memory address or nil pointer dereference [recovered]
  3. panic: runtime error: invalid memory address or nil pointer dereference
  4. [signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x76ddf0]
  5. goroutine 8 [running]:
  6. testing.tRunner.func1.2({0x841660, 0xbeb720})
  7. /usr/local/go/src/testing/testing.go:1396 +0x24e
  8. testing.tRunner.func1()
  9. /usr/local/go/src/testing/testing.go:1399 +0x39f
  10. panic({0x841660, 0xbeb720})
  11. /usr/local/go/src/runtime/panic.go:884 +0x212
  12. html/template.(*Template).lookupAndEscapeTemplate(0x0, {0xc000036640, 0x4c})
  13. /usr/local/go/src/html/template/template.go:146 +0x50
  14. html/template.(*Template).ExecuteTemplate(0x8ab914?, {0x7faf3da99c78, 0xc0001c4340}, {0xc000036640?, 0x0?}, {0x8148c0, 0xc0001beee0})
  15. /usr/local/go/src/html/template/template.go:135 +0x38
  16. github.com/vedicsociety/brucheion.renderLoginTemplate({0x9691b8?, 0xc0001c4340}, {0x8ab914?, 0xbff840?}, 0xc0001a0600?)
  17. /home/abdurrehman/Documents/work/martin-gluckman/Brucheion/templates.go:52 +0x85
  18. github.com/vedicsociety/brucheion.loginGET({0x9691b8, 0xc0001c4340}, 0xc0001b8900?)
  19. /home/abdurrehman/Documents/work/martin-gluckman/Brucheion/login.go:72 +0x325
  20. net/http.HandlerFunc.ServeHTTP(0xc0001a0500?, {0x9691b8?, 0xc0001c4340?}, 0x203000?)
  21. /usr/local/go/src/net/http/server.go:2109 +0x2f
  22. github.com/gorilla/mux.(*Router).ServeHTTP(0xc0001c80c0, {0x9691b8, 0xc0001c4340}, 0xc0001a0400)
  23. /home/abdurrehman/go/pkg/mod/github.com/gorilla/mux@v1.7.4/mux.go:210 +0x1cf
  24. github.com/vedicsociety/brucheion.executeRequest(0x8aa772?)
  25. /home/abdurrehman/Documents/work/martin-gluckman/Brucheion/api_test.go:41 +0xaf
  26. github.com/vedicsociety/brucheion.TestLoginRequest(0x0?)
  27. /home/abdurrehman/Documents/work/martin-gluckman/Brucheion/api_test.go:32 +0x7f
  28. testing.tRunner(0xc0000d7860, 0x8ea660)
  29. /usr/local/go/src/testing/testing.go:1446 +0x10b
  30. created by testing.(*T).Run
  31. /usr/local/go/src/testing/testing.go:1493 +0x35f
  32. exit status 2
  33. FAIL github.com/vedicsociety/brucheion 0.005s

单元测试

  1. func TestLoginRequest(t *testing.T) {
  2. setupRouter()
  3. req, _ := http.NewRequest("GET", "/login/", nil)
  4. response := executeRequest(req)
  5. assert.Equal(t, 200, response.Code)
  6. }
  7. // Helper functions.
  8. func executeRequest(req *http.Request) *httptest.ResponseRecorder {
  9. requestRecorder := httptest.NewRecorder()
  10. router.ServeHTTP(requestRecorder, req)
  11. return requestRecorder
  12. }
  13. func setupRouter() {
  14. router = mux.NewRouter().StrictSlash(true)
  15. router.HandleFunc("/login/", loginGET).Methods("GET")
  16. router.NotFoundHandler = http.HandlerFunc(NotFoundRedirect)
  17. }

问题似乎出在这里

  1. func renderLoginTemplate(res http.ResponseWriter, tmpl string, loginPage *LoginPage) {
  2. fmt.Println(generateFilePath(tmpl))
  3. err := templates.ExecuteTemplate(res, generateFilePath(tmpl), loginPage)
  4. if err != nil {
  5. http.Error(res, err.Error(), http.StatusInternalServerError)
  6. }
  7. }
  8. func generateFilePath(tName string) string {
  9. s, err := os.Getwd()
  10. if err != nil {
  11. panic(err)
  12. }
  13. return filepath.Join(s, "/tmpl/", tName+".html")
  14. }

templates.ExecuteTemplate 函数有问题。我遇到了这两个 StackOverflow 的问题(链接1链接2),开发者似乎遇到了相同的问题,因此创建了 generateFilePath 函数来获取绝对路径,但是没有成功。

英文:

So I have a simple application that is supposed to render an Html page on GET requests /login/. The requests work fine when I run the web server locally, but when I run unit tests there seems to be an error.(go test -v is being used to run the tests.)

  1. --- FAIL: TestLoginRequest (0.00s)
  2. panic: runtime error: invalid memory address or nil pointer dereference [recovered]
  3. panic: runtime error: invalid memory address or nil pointer dereference
  4. [signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x76ddf0]
  5. goroutine 8 [running]:
  6. testing.tRunner.func1.2({0x841660, 0xbeb720})
  7. /usr/local/go/src/testing/testing.go:1396 +0x24e
  8. testing.tRunner.func1()
  9. /usr/local/go/src/testing/testing.go:1399 +0x39f
  10. panic({0x841660, 0xbeb720})
  11. /usr/local/go/src/runtime/panic.go:884 +0x212
  12. html/template.(*Template).lookupAndEscapeTemplate(0x0, {0xc000036640, 0x4c})
  13. /usr/local/go/src/html/template/template.go:146 +0x50
  14. html/template.(*Template).ExecuteTemplate(0x8ab914?, {0x7faf3da99c78, 0xc0001c4340}, {0xc000036640?, 0x0?}, {0x8148c0, 0xc0001beee0})
  15. /usr/local/go/src/html/template/template.go:135 +0x38
  16. github.com/vedicsociety/brucheion.renderLoginTemplate({0x9691b8?, 0xc0001c4340}, {0x8ab914?, 0xbff840?}, 0xc0001a0600?)
  17. /home/abdurrehman/Documents/work/martin-gluckman/Brucheion/templates.go:52 +0x85
  18. github.com/vedicsociety/brucheion.loginGET({0x9691b8, 0xc0001c4340}, 0xc0001b8900?)
  19. /home/abdurrehman/Documents/work/martin-gluckman/Brucheion/login.go:72 +0x325
  20. net/http.HandlerFunc.ServeHTTP(0xc0001a0500?, {0x9691b8?, 0xc0001c4340?}, 0x203000?)
  21. /usr/local/go/src/net/http/server.go:2109 +0x2f
  22. github.com/gorilla/mux.(*Router).ServeHTTP(0xc0001c80c0, {0x9691b8, 0xc0001c4340}, 0xc0001a0400)
  23. /home/abdurrehman/go/pkg/mod/github.com/gorilla/mux@v1.7.4/mux.go:210 +0x1cf
  24. github.com/vedicsociety/brucheion.executeRequest(0x8aa772?)
  25. /home/abdurrehman/Documents/work/martin-gluckman/Brucheion/api_test.go:41 +0xaf
  26. github.com/vedicsociety/brucheion.TestLoginRequest(0x0?)
  27. /home/abdurrehman/Documents/work/martin-gluckman/Brucheion/api_test.go:32 +0x7f
  28. testing.tRunner(0xc0000d7860, 0x8ea660)
  29. /usr/local/go/src/testing/testing.go:1446 +0x10b
  30. created by testing.(*T).Run
  31. /usr/local/go/src/testing/testing.go:1493 +0x35f
  32. exit status 2
  33. FAIL github.com/vedicsociety/brucheion 0.005s

unit test

  1. func TestLoginRequest(t *testing.T) {
  2. setupRouter()
  3. req, _ := http.NewRequest("GET", "/login/", nil)
  4. response := executeRequest(req)
  5. assert.Equal(t, 200, response.Code)
  6. }
  7. // Helper functions.
  8. func executeRequest(req *http.Request) *httptest.ResponseRecorder {
  9. requestRecorder := httptest.NewRecorder()
  10. router.ServeHTTP(requestRecorder, req)
  11. return requestRecorder
  12. }
  13. func setupRouter() {
  14. router = mux.NewRouter().StrictSlash(true)
  15. router.HandleFunc("/login/", loginGET).Methods("GET")
  16. router.NotFoundHandler = http.HandlerFunc(NotFoundRedirect)
  17. }

The issue seems to be here

  1. func renderLoginTemplate(res http.ResponseWriter, tmpl string, loginPage *LoginPage) {
  2. fmt.Println(generateFilePath(tmpl))
  3. err := templates.ExecuteTemplate(res, generateFilePath(tmpl), loginPage)
  4. if err != nil {
  5. http.Error(res, err.Error(), http.StatusInternalServerError)
  6. }
  7. }
  8. func generateFilePath(tName string) string {
  9. s, err := os.Getwd()
  10. if err != nil {
  11. panic(err)
  12. }
  13. return filepath.Join(s, "/tmpl/", tName+".html")
  14. }

The templates.ExecuteTemplate function is being problematic. I came across these two StackOverflow questions (link1, link2) where the developer seems to have encountered the same issue and thus created the function generateFilePath to get an absolute path haven't had any luck.

答案1

得分: 0

http.NewRequest 返回一个 *http.Request 实例,用于 客户端 发送 出站请求loginGET 是一个处理程序,它期望一个用于 服务器*http.Request 实例,用于 入站请求。请勿将 http.NewRequest 的输出直接作为 ServeHTTP 的参数。

对于处理程序测试,不要使用 http.NewRequest,而是使用 httptest.NewRequest"NewRequest 返回一个新的 入站服务器请求,适用于传递给 http.Handler 进行测试。"

英文:

http.NewRequest returns an instance of *http.Request that is intended for clients to send outgoing requests. loginGET is a handler that expects an instance of *http.Request intended for servers, for an incoming request. Do NOT use the output of http.NewRequest as a direct argument to ServeHTTP.

For handler tests, instead of http.NewRequest, use httptest.NewRequest: "NewRequest returns a new incoming server Request, suitable for passing to an http.Handler for testing."

huangapple
  • 本文由 发表于 2022年8月21日 13:04:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/73431763.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定