简体   繁体   中英

Unit testing http json response in Golang

I am using gin as my http server and sending back an empty array in json as my response:

c.JSON(http.StatusOK, []string{})

The resulting json string I get is "[]\n" . The newline is added by the json Encoder object, seehere .

Using goconvey , I could test my json like

So(response.Body.String(), ShouldEqual, "[]\n")

But is there a better way to generate the expected json string than just adding a newline to all of them?

You should first unmarshal the body of the response into a struct and compare against the resulting object. Example:

result := []string{}
if err := json.NewDecoder(response.Body).Decode(&result); err != nil {
    log.Fatalln(err)
}
So(len(result), ShouldEqual, 0)

将主体解组为结构并使用 Gocheck 的 DeepEquals https://godoc.org/launchpad.net/gocheck

You may find jsonassert useful. It has no dependencies outside the standard library and allows you to verify that JSON strings are semantically equivalent to a JSON string you expect.

In your case:

// white space is ignored, no need for \n
jsonassert.New(t).Assertf(response.Body().String(), "[]")

It can handle any form of JSON, and has very friendly assertion error messages.

Disclaimer: I wrote this package.

I made it this way. Because I don't want to include an extra library.

tc := testCase{
    w: httptest.NewRecorder(),
    wantResponse: mustJson(t, map[string]string{"message": "unauthorized"}),
}
...

if tc.wantResponse != tc.w.Body.String() {
    t.Errorf("want %s, got %s", tt.wantResponse, tt.w.Body.String())
}

...
func mustJson(t *testing.T, v interface{}) string {
    t.Helper()
    out, err := json.Marshal(v)
    if err != nil {
        t.Fatal(err)
    }
    return string(out)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM