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/mux@v1.7.4/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.
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."