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

Time:08-21

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."

  • Related