使用golang中的json编组进行深度相等性测试

huangapple go评论150阅读模式
英文:

Testing for deep equality with json marshaling in golang

问题

给定这两个测试用例:

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

其中testMarshalUnmarshal辅助函数只是将对象编组为JSON,然后再解组出来:

func testMarshalUnmarshal(t *testing.T, in map[string]interface{}) {
	//将对象编组为字符串
	jsb, err := json.Marshal(in);
	if err != nil {
		log.Printf("无法编组消息")
		t.FailNow()
	}

	//解组为一个映射
	res := make(map[string]interface{})
	if err := json.Unmarshal(jsb, &res); err != nil { t.FailNow() }

	if !reflect.DeepEqual(in, res) {
		log.Printf("\n期望值 %#v\n但得到了  %#v", in, res)
		t.FailNow()
	}
}

为什么第一个测试用例通过了,而第二个测试用例失败了?测试的输出如下:

期望值 map[string]interface {}{"a":5}
但得到了  map[string]interface {}{"a":5}
--- FAIL: TestEqualWhat (0.00 秒)

这里是类似的代码在Go Playground上,这样你可以轻松地尝试一下。

英文:

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.

答案1

得分: 16

我弄清楚了!JSON只有一种数值类型,即浮点数,所以在编组/解组过程中,所有整数都会转换为Float64。因此,在res映射中,5是一个float64而不是一个int。

这里是一个Go Playground,提供了我所说的上下文和证据。

英文:

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.

huangapple
  • 本文由 发表于 2013年6月26日 03:06:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/17305512.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定