如何比较两个 JSON 请求?

短篇小说:如何比较两个 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). 我猜 encoding/json 不喜欢空接口,所以问题是如何比较两个 JSON 块?字符串比较容易出错,所以我试图避免这种情况。


阿晨1998
浏览 196回答 3
3回答

MMMHUHU

这里的派对超级迟到。golang 中有一个流行的测试包叫做 require github.com/stretchr/testify/require,它会为你做这件事。func TestJsonEquality(t *testing.t) {   expected := `{"a": 1, "b": 2} `  actual := ` {"b":   2, "a":   1}`  require.JSONEq(t, expected, actual)}GoDocs:https ://godoc.org/github.com/stretchr/testify/require#JSONEqf

波斯汪

您需要将指针传递给Decode和Unmarshal。我用和建立了一个可运行的样本,两者都返回。您可以通过使用或包装您的预期内容来将请求正文与您的静态预期内容进行比较(就像您在问题中尝试做的那样)。这是代码:func JSONEqual(a, b io.Reader)JSONBytesEqual(a, b []byte)(bool, error)bytes.NewBufferstrings.NewReaderpackage mainimport (&nbsp; &nbsp; "encoding/json"&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "io"&nbsp; &nbsp; "reflect")// JSONEqual compares the JSON from two Readers.func JSONEqual(a, b io.Reader) (bool, error) {&nbsp; &nbsp; var j, j2 interface{}&nbsp; &nbsp; d := json.NewDecoder(a)&nbsp; &nbsp; if err := d.Decode(&j); err != nil {&nbsp; &nbsp; &nbsp; &nbsp; return false, err&nbsp; &nbsp; }&nbsp; &nbsp; d = json.NewDecoder(b)&nbsp; &nbsp; if err := d.Decode(&j2); err != nil {&nbsp; &nbsp; &nbsp; &nbsp; return false, err&nbsp; &nbsp; }&nbsp; &nbsp; return reflect.DeepEqual(j2, j), nil}// JSONBytesEqual compares the JSON in two byte slices.func JSONBytesEqual(a, b []byte) (bool, error) {&nbsp; &nbsp; var j, j2 interface{}&nbsp; &nbsp; if err := json.Unmarshal(a, &j); err != nil {&nbsp; &nbsp; &nbsp; &nbsp; return false, err&nbsp; &nbsp; }&nbsp; &nbsp; if err := json.Unmarshal(b, &j2); err != nil {&nbsp; &nbsp; &nbsp; &nbsp; return false, err&nbsp; &nbsp; }&nbsp; &nbsp; return reflect.DeepEqual(j2, j), nil}func main() {&nbsp; &nbsp; a := []byte(`{"x": ["y",42]}`)&nbsp; &nbsp; b := []byte(`{"x":&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ["y",&nbsp; 42]}`)&nbsp; &nbsp; c := []byte(`{"z": ["y", "42"]}`)&nbsp; &nbsp; empty := []byte{}&nbsp; &nbsp; bad := []byte(`{this? this is a test.}`)&nbsp; &nbsp; eq, err := JSONBytesEqual(a, b)&nbsp; &nbsp; fmt.Println("a=b\t", eq, "with error", err)&nbsp; &nbsp; eq, err = JSONBytesEqual(a, c)&nbsp; &nbsp; fmt.Println("a=c\t", eq, "with error", err)&nbsp; &nbsp; eq, err = JSONBytesEqual(a, empty)&nbsp; &nbsp; fmt.Println("a=empty\t", eq, "with error", err)&nbsp; &nbsp; eq, err = JSONBytesEqual(a, bad)&nbsp; &nbsp; fmt.Println("a=bad\t", eq, "with error", err)}它输出:a=b&nbsp; true with error <nil>a=c&nbsp; false with error <nil>a=empty&nbsp; false with error EOFa=bad&nbsp; &nbsp; false with error invalid character 't' looking for beginning of object key string

泛舟湖上清波郎朗

我写了一个工具来比较基于 http json 的响应,但我忽略了顺序。可以看一下实现比较和抓取Equal函数的包:https : //github.com/emacampolo/gomparator/blob/master/json_util.go#L10例如:b1 := []byte(`{"x": {"t": 1, "s": 2}, "z": 1}`)b2 := []byte(`{"z": 1, "x": {"s": 2, "t": 1}}`)j1, _ := Unmarshal(b1)j2, _ := Unmarshal(b2)assert.True(t, Equal(j1, j2))
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go