短篇小说:如何比较两个JSON块?下面的代码错误。
var j, j2 interface{} b := []byte(srv.req) if err := json.Unmarshal(b, j); err !=nil{ t.Errorf("err %v, req %s", err, b) return } d := json.NewDecoder(r.Body) if err := d.Decode(j2); err !=nil{ t.Error(err) return } if !reflect.DeepEqual(j2, j){ t.Errorf("j %v, j2 %v", j, j2) return }
长话短说:我正在做一些E2E测试,其中一部分我需要将请求的JSON正文与接收到的JSON进行比较。为此,我尝试将期望的接收到的json解组到一个空接口(以避免任何类型错误),但出现错误: json: Unmarshal(nil)。我猜编码/ json不喜欢空接口,所以问题是如何比较两个JSON块?字符串比较容易出错,因此我尝试避免这种情况。
json: Unmarshal(nil)
您需要将指针传递给Decode和Unmarshal。我用和放了一个可运行的示例,都返回。您可以使用或封装您的期望内容,从而将请求正文与您的静态期望内容进行比较(就像您要在问题中尝试做的那样)。这是代码:func JSONEqual(a, b io.Reader)``JSONBytesEqual(a, b []byte)``(bool, error)``bytes.NewBuffer``strings.NewReader
Decode
Unmarshal
func JSONEqual(a, b io.Reader)``JSONBytesEqual(a, b []byte)``(bool, error)``bytes.NewBuffer``strings.NewReader
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) }
它输出:
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