/ / Como comparar duas solicitações JSON? - json, vai

Como comparar duas solicitações JSON? - json, vai

Breve História: Como posso comparar dois trechos de JSON? O código abaixo está errado.

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
}

Longa história: Eu estou fazendo alguns testes E2E e parte disso eu preciso comparar o corpo JSON solicitado com o JSON recebido. Para fazer isso eu tentei unmarshal o json esperado e recebido para uma interface vazia (para evitar erros de qualquer tipo), mas Eu recebo um erro: json: Unmarshal(nil). Eu acho que codificação / json não gosta da interface vazia, então a questão é como posso comparar dois pedaços de JSON? Uma comparação de seqüência de caracteres seria propenso a erros, então eu estou tentando evitar isso.

Respostas:

2 para resposta № 1

Você precisa passar ponteiros para Decode e Unmarshal. Eu coloquei um amostra executável com func JSONEqual(a, b io.Reader) e JSONBytesEqual(a, b []byte)ambos retornando (bool, error). Você pode comparar um corpo de solicitação ao seu conteúdo esperado estático (como você está tentando fazer na pergunta) envolvendo o conteúdo esperado usando bytes.NewBuffer ou strings.NewReader. Aqui está o código:

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=bt", eq, "with error", err)
eq, err = JSONBytesEqual(a, c)
fmt.Println("a=ct", eq, "with error", err)
eq, err = JSONBytesEqual(a, empty)
fmt.Println("a=emptyt", eq, "with error", err)
eq, err = JSONBytesEqual(a, bad)
fmt.Println("a=badt", eq, "with error", err)
}

Ele produz:

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