I try to test if my http handler is returning the right values inside the body.
This is my handler function
func Index(w http.ResponseWriter, r *http.Request){
message := `{"status": "OK"}`
w.WriteHeader(http.StatusOK)
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
if err := json.NewEncoder(w).Encode(message); err != nil {
panic(err)
}
}
This is my test
func TestIndex(t *testing.T){
req, err := http.NewRequest("GET", "/", nil)
if err != nil {
t.Fatal(err)
}
rr := httptest.NewRecorder()
handler := http.HandlerFunc(Index)
handler.ServeHTTP(rr, req)
expected := `"{"status": "OK"}"`
if rr.Body.String() != expected {
t.Errorf("handler returned unexpected body: got %v want %v",
rr.Body.String(), expected)
}
}
The result of the test is:
handlers_test.go:244: handler returned unexpected body: got "{\"status\": \"OK\"}"
want {"status": "OK"}
I think the escaping of the " is because of the json Encode, but even if I change the expected to
expected := `"{\"status\": \"OK\"}"`
it does not work, than the result of the test is
handlers_test.go:244: handler returned unexpected body: got "{\"status\": \"OK\"}"
want "{\"status\": \"OK\"}"
In the docs I found something that json encode appends a newline character, but I did not manage to get the test working even with that information :-/
In advance, thanks for your help.
The message you send:
message := `{"status": "OK"}`
Is already a valid JSON text, you don't need any further JSON encoding / processing on it. Just send it as-is:
func Index(w http.ResponseWriter, r *http.Request){
message := `{"status": "OK"}`
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
io.WriteString(w, message)
}
Also note that if your response code is http.StatusOK
, you don't need to set that explicitly, as that is the default if you don't set it.
And then simply expect the following response:
expected := `{"status": "OK"}`
Explaining your original code:
In your original code you JSON-marshaled a single string
value, whose content was {"status": "OK"}
. JSON encoding will quote this text into a valid JSON string (prefix quotation marks with a backslash), put inside quotes, and also appends a newline character. So this becomes the raw string:
expected := `"{\"status\": \"OK\"}"
`
Using this expected
value, your test passes, but again, what you want is in the first part of this answer.
If you want to use an interpreted string literal to describe the expected
value, this is how it could look like:
expected := "\"{\\\"status\\\": \\\"OK\\\"}\"
"
The linebreak was the problem. I managed to solve it with adding strings.TrimRight and cut if right off the string.
if strings.TrimRight(rr.Body.String(), "
") != expected {
t.Errorf("handler returned unexpected body: got %v want %v",
rr.Body.String(), expected)
}