Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing for deep equality with json marshaling in golang

Tags:

json

go

Given these two test cases:

func TestEqualWhat(t *testing.T) {
    testMarshalUnmarshal(t, map[string]interface{}{"a":"b"})
    testMarshalUnmarshal(t, map[string]interface{}{"a":5})
}

Where the testMarshalUnmarshal helper just marshals to json and back out:

func testMarshalUnmarshal(t *testing.T, in map[string]interface{}) {
    //marshal the object to a string
    jsb, err := json.Marshal(in);
    if err != nil {
        log.Printf("Unable to marshal msg")
        t.FailNow()
    }

    //unmarshal to a map
    res := make(map[string]interface{})
    if err := json.Unmarshal(jsb, &res); err != nil { t.FailNow() }

    if !reflect.DeepEqual(in, res) {
        log.Printf("\nExpected %#v\nbut got  %#v", in, res)
        t.FailNow()
    }
}

Why does the first test case pass and the second fail? The output of the test is this:

Expected map[string]interface {}{"a":5}
but got  map[string]interface {}{"a":5}
--- FAIL: TestEqualWhat (0.00 seconds)

Here is similar code on the go playground so you can have a hack at it easily.

like image 344
llimllib Avatar asked Jun 25 '13 19:06

llimllib


1 Answers

I figured it out! JSON only has one numerical type, which is floating point, so all integers are converted to Float64 in the marshal/unmarshal process. So, in the res map, the 5 is a float64 instead of an int.

Here is a go playground that provides context and evidence of what I'm talking about.

like image 61
llimllib Avatar answered Nov 05 '22 02:11

llimllib