panic: runtime error: invalid memory address or nil pointer dereference
peterbe opened this issue · 3 comments
I bet I'm doing something wrong being a noob and all but it seems like it should work:
:~/dev/GO/autocompeter (integration-test +%)$ go test -v
=== RUN TestHandleIndexReturnsWithStatusOK
--- FAIL: TestHandleIndexReturnsWithStatusOK (0.00s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0xc8 pc=0xf2fba]
goroutine 5 [running]:
testing.func·006()
/opt/boxen/homebrew/Cellar/go/1.4.1/libexec/src/testing/testing.go:441 +0x181
github.com/unrolled/render.(*Render).HTML(0x0, 0x823440, 0xc20800a0c0, 0xc8, 0x420370, 0x5, 0x0, 0x0, 0x0, 0x0, ...)
/Users/peterbe/dev/GO/src/github.com/unrolled/render/render.go:249 +0x2a
_/Users/peterbe/dev/GO/autocompeter.IndexHandler(0x823440, 0xc20800a0c0, 0xc20801e5b0)
/Users/peterbe/dev/GO/autocompeter/main.go:80 +0x8a
_/Users/peterbe/dev/GO/autocompeter.TestHandleIndexReturnsWithStatusOK(0xc20806a090)
/Users/peterbe/dev/GO/autocompeter/main_test.go:13 +0x175
testing.tRunner(0xc20806a090, 0x752690)
/opt/boxen/homebrew/Cellar/go/1.4.1/libexec/src/testing/testing.go:447 +0xbf
created by testing.RunTests
/opt/boxen/homebrew/Cellar/go/1.4.1/libexec/src/testing/testing.go:555 +0xa8b
goroutine 1 [chan receive]:
testing.RunTests(0x5197e8, 0x752690, 0x1, 0x1, 0x75d301)
/opt/boxen/homebrew/Cellar/go/1.4.1/libexec/src/testing/testing.go:556 +0xad6
testing.(*M).Run(0xc20802a0f0, 0x764780)
/opt/boxen/homebrew/Cellar/go/1.4.1/libexec/src/testing/testing.go:485 +0x6c
main.main()
_/Users/peterbe/dev/GO/autocompeter/_test/_testmain.go:52 +0x1d5
exit status 2
FAIL _/Users/peterbe/dev/GO/autocompeter 0.021s
The test is extremely simple so far:
package main
import (
"net/http"
"net/http/httptest"
"testing"
)
func TestHandleIndexReturnsWithStatusOK(t *testing.T) {
request, _ := http.NewRequest("GET", "/", nil)
response := httptest.NewRecorder()
IndexHandler(response, request)
if response.Code != http.StatusOK {
t.Fatalf("Non-expected status code%v:\n\tbody: %v", "200", response.Code)
}
}
And in main.go
there's a bunch of other stuff but the things that matter should be:
package main
import "github.com/unrolled/render"
func IndexHandler(w http.ResponseWriter, req *http.Request) {
// this assumes there's a `templates/index.tmpl` file
renderer.HTML(w, http.StatusOK, "index", nil)
}
var (
renderer *render.Render
debug = true
)
func main() {
...
renderer = render.New(render.Options{
IndentJSON: debug,
IsDevelopment: debug,
})
...
mux := mux.NewRouter()
mux.HandleFunc("/", IndexHandler).Methods("GET", "HEAD")
n := negroni.Classic()
n.UseHandler(mux)
n.Run(fmt.Sprintf(":%d", port))
}
Perhaps that's now how you're supposed to do testing of http handlers.
Hey Peter, you code looks good, but we need to initial the renderer
variable before the handler can be called in your test.
func TestHandleIndexReturnsWithStatusOK(t *testing.T) {
request, _ := http.NewRequest("GET", "/", nil)
response := httptest.NewRecorder()
// Since main isn't called for the test, we need to initialize the renderer var manually.
renderer = render.New(render.Options{
IndentJSON: true,
IsDevelopment: true,
})
IndexHandler(response, request)
if response.Code != http.StatusOK {
t.Fatalf("Non-expected status code%v:\n\tbody: %v", "200", response.Code)
}
}
If you don't have to much customization, you could initial the renderer when you declare it:
var (
debug = true
renderer = render.New(render.Options{
IndentJSON: debug,
IsDevelopment: debug,
})
)
With that, you wouldn't need to change your test code.
Let me know if this helps!
Yay! That works. Thing is, I want the debug
to come in from a flag which I have in my main()
. E.g. flag.BoolVar(&debug, "debug", false, "Debug mode")
So, instead I made a default renderer
that does not use debug
and then I override it in main()
later. Now I get working tests and ability to use the debug when running the server on the command line.
var (
debug = true
renderer = render.New()
)
func main() {
flag.BoolVar(&debug, "debug", false, "Debug mode")
renderer = render.New(render.Options{
IndentJSON: debug,
IsDevelopment: debug,
})
}
👍