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.)
--- FAIL: TestLoginRequest (0.00s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x76ddf0]
goroutine 8 [running]:
testing.tRunner.func1.2({0x841660, 0xbeb720})
/usr/local/go/src/testing/testing.go:1396 0x24e
testing.tRunner.func1()
/usr/local/go/src/testing/testing.go:1399 0x39f
panic({0x841660, 0xbeb720})
/usr/local/go/src/runtime/panic.go:884 0x212
html/template.(*Template).lookupAndEscapeTemplate(0x0, {0xc000036640, 0x4c})
/usr/local/go/src/html/template/template.go:146 0x50
html/template.(*Template).ExecuteTemplate(0x8ab914?, {0x7faf3da99c78, 0xc0001c4340}, {0xc000036640?, 0x0?}, {0x8148c0, 0xc0001beee0})
/usr/local/go/src/html/template/template.go:135 0x38
github.com/vedicsociety/brucheion.renderLoginTemplate({0x9691b8?, 0xc0001c4340}, {0x8ab914?, 0xbff840?}, 0xc0001a0600?)
/home/abdurrehman/Documents/work/martin-gluckman/Brucheion/templates.go:52 0x85
github.com/vedicsociety/brucheion.loginGET({0x9691b8, 0xc0001c4340}, 0xc0001b8900?)
/home/abdurrehman/Documents/work/martin-gluckman/Brucheion/login.go:72 0x325
net/http.HandlerFunc.ServeHTTP(0xc0001a0500?, {0x9691b8?, 0xc0001c4340?}, 0x203000?)
/usr/local/go/src/net/http/server.go:2109 0x2f
github.com/gorilla/mux.(*Router).ServeHTTP(0xc0001c80c0, {0x9691b8, 0xc0001c4340}, 0xc0001a0400)
/home/abdurrehman/go/pkg/mod/github.com/gorilla/[email protected]/mux.go:210 0x1cf
github.com/vedicsociety/brucheion.executeRequest(0x8aa772?)
/home/abdurrehman/Documents/work/martin-gluckman/Brucheion/api_test.go:41 0xaf
github.com/vedicsociety/brucheion.TestLoginRequest(0x0?)
/home/abdurrehman/Documents/work/martin-gluckman/Brucheion/api_test.go:32 0x7f
testing.tRunner(0xc0000d7860, 0x8ea660)
/usr/local/go/src/testing/testing.go:1446 0x10b
created by testing.(*T).Run
/usr/local/go/src/testing/testing.go:1493 0x35f
exit status 2
FAIL github.com/vedicsociety/brucheion 0.005s
unit test
func TestLoginRequest(t *testing.T) {
setupRouter()
req, _ := http.NewRequest("GET", "/login/", nil)
response := executeRequest(req)
assert.Equal(t, 200, response.Code)
}
// Helper functions.
func executeRequest(req *http.Request) *httptest.ResponseRecorder {
requestRecorder := httptest.NewRecorder()
router.ServeHTTP(requestRecorder, req)
return requestRecorder
}
func setupRouter() {
router = mux.NewRouter().StrictSlash(true)
router.HandleFunc("/login/", loginGET).Methods("GET")
router.NotFoundHandler = http.HandlerFunc(NotFoundRedirect)
}
The issue seems to be here
func renderLoginTemplate(res http.ResponseWriter, tmpl string, loginPage *LoginPage) {
fmt.Println(generateFilePath(tmpl))
err := templates.ExecuteTemplate(res, generateFilePath(tmpl), loginPage)
if err != nil {
http.Error(res, err.Error(), http.StatusInternalServerError)
}
}
func generateFilePath(tName string) string {
s, err := os.Getwd()
if err != nil {
panic(err)
}
return filepath.Join(s, "/tmpl/", tName ".html")
}
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.
CodePudding user response:
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."