Bob
Bob

Reputation: 666

Golang unittest http handler

I want to make a simple server that can receive web hook requests from services and deal with them for me. And for fun I wanted to build that in Go, since that sounds like a nice language and this is a simple project to start with.

The server seems to be working fine, but I can't get my unittest to work. On inspection it seems that every url gives a 404. What am I doing wrong?

main.go

package main

import (
    "fmt"
    "log"
    "net/http"
)

func pingHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "{\"check\": \"online\"}")
}

func main() {
    // Start server
    log.Print("Starting server")
    http.HandleFunc("/ping", pingHandler)
    log.Fatal(http.ListenAndServe(":7080", nil))
}

main_test.go

package main

import (
    "fmt"
    "net/http"
    "net/http/httptest"
    "testing"
)

func TestPingHandler(t *testing.T) {
    req, err := http.NewRequest("GET", "/ping", nil)
    if err != nil {
        t.Fatal(err)
    }
    rr := httptest.NewRecorder()
    http.DefaultServeMux.ServeHTTP(rr, req)

    status := rr.Code
    fmt.Println(status)
}

Upvotes: 1

Views: 1540

Answers (1)

Adrian
Adrian

Reputation: 46413

Your handler is registered in main, but main is not invoked when you're running unit tests. So, when you try to test via DefaultMux, no handlers are registered, and you get a 404. However, generally you test the handler, not the mux; so instead of this line:

http.DefaultServeMux.ServeHTTP(rr, req)

You would instead test:

pingHandler(rr, req)

Which will work even though main is not executed to register the handler, because you're now testing the handler directly.

You should also use httptest.NewRequest to create requests for testing; http.NewRequest is for creating requests for use in a Client.

Upvotes: 2

Related Questions