drhe80011 2015-09-05 02:15
浏览 51
已采纳

如何比较两个JSON请求?

Short Story: How can I compare two chunks of JSON? The code below errors out.

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
}

Long Story: I'm doing some E2E testings and part of this I need to compare the requested JSON body with the received JSON. To do this I've tried to unmarshal the expected and received json to an empty interface (to avoid any type mistakes) but I get an error: json: Unmarshal(nil). I guess encoding/json doesn't like the empty interface so the question is how can I compare two chunks of JSON? A string comparison would be error prone so I'm trying to avoid that.

  • 写回答

2条回答 默认 最新

  • dpnw86361 2015-09-05 03:06
    关注

    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
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥50 求一段sql语句,遇到小难题了,可以50米解决
  • ¥15 速求,对多种商品的购买力优化问题(用遗传算法、枚举法、粒子群算法、模拟退火算法等方法求解)
  • ¥15 jdk环境变量配置,cmd中Javac运行不了,找不到问题求解答
  • ¥100 速求!商品购买力最优化问题(用遗传算法求解,给出python代码)
  • ¥15 虚拟机检测,可以是封装好的DLL,可付费
  • ¥15 kafka无法正常启动(只启动了一瞬间会然后挂了)
  • ¥15 Workbench中材料库无法更新,如何解决?
  • ¥20 如何推断此服务器配置
  • ¥15 关于github的项目怎么在pycharm上面运行
  • ¥15 内存地址视频流转RTMP