You need to pass pointers to Decode and Unmarshal. I put up a runnable sample with func JSONEqual(a, b io.Reader) and JSONBytesEqual(a, b []byte), both returning (bool, error). You can compare a request body to your static expected content (like you're trying to do in the question) by wrapping your expected content using bytes.NewBuffer or strings.NewReader. Here's the code:
package main import ( "encoding/json" "fmt" "io" "reflect" ) // JSONEqual compares the JSON from two Readers. func JSONEqual(a, b io.Reader) (bool, error) { var j, j2 interface{} d := json.NewDecoder(a) if err := d.Decode(&j); err != nil { return false, err } d = json.NewDecoder(b) if err := d.Decode(&j2); err != nil { return false, err } return reflect.DeepEqual(j2, j), nil } // JSONBytesEqual compares the JSON in two byte slices. func JSONBytesEqual(a, b []byte) (bool, error) { var j, j2 interface{} if err := json.Unmarshal(a, &j); err != nil { return false, err } if err := json.Unmarshal(b, &j2); err != nil { return false, err } return reflect.DeepEqual(j2, j), nil } func main() { a := []byte(`{"x": ["y",42]}`) b := []byte(`{"x": ["y", 42]}`) c := []byte(`{"z": ["y", "42"]}`) empty := []byte{} bad := []byte(`{this? this is a test.}`) eq, err := JSONBytesEqual(a, b) fmt.Println("a=b\t", eq, "with error", err) eq, err = JSONBytesEqual(a, c) fmt.Println("a=c\t", eq, "with error", err) eq, err = JSONBytesEqual(a, empty) fmt.Println("a=empty\t", eq, "with error", err) eq, err = JSONBytesEqual(a, bad) fmt.Println("a=bad\t", eq, "with error", err) }
It outputs:
a=b true with error <nil> a=c false with error <nil> a=empty false with error EOF a=bad false with error invalid character 't' looking for beginning of object key string
j, j2 := map[string]interface{}{}, map[string]interface{}{}. I know you want a self-contained example for the best chance of a good answer on SO, though. :)Decode/Unmarshal(complete examples still help though!).