8

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, see here.

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?

3
  • 4
    Comparing against the raw output produced by a marshal is problematic since anytime you use a map the order is not guaranteed. In my tests I always unmarshal then compare. Commented Nov 11, 2015 at 21:11
  • @jmaloney, Can you please give me a code sample? Commented Nov 11, 2015 at 21:22
  • 1
    play.golang.org/p/vA-n_f9VoI Commented Nov 11, 2015 at 21:35

4 Answers 4

5

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)
Sign up to request clarification or add additional context in comments.

Comments

2

Unmarshal the body into a struct and the use Gocheck's DeepEquals https://godoc.org/launchpad.net/gocheck

Comments

2

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.

Comments

0

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)
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.