jefferyjob/go-easy-utils

There is a bug in how jsonToStruct parses maps and slices.

jefferyjob opened this issue · 1 comments

There is a bug in how jsonToStruct parses maps and slices.

  1. Does not support parsing map type
  2. Parse the slice type, if the data type is inconsistent, panic error
type Target struct {
	Followed map[string]bool `json:"followed"`
	Fids     []string        `json:"fids"`
}

func TestJsonToStruct(t *testing.T) {
	data := `
	{
		"followed": {
			"43015653": true,
			"43015666": false
		},
		"fids": ["43015653",43015666]
	}
	`

	var event Target
	err := JsonToStruct(data, &event)
	fmt.Printf("%+v, err:%s \n", event, err)
}

The specific error description is as follows

panic: reflect.Set: value of type float64 is not assignable to type string [recovered]
	panic: reflect.Set: value of type float64 is not assignable to type string

已修复该问题,单元测试验证代码如下:

验证内容包括:

  • 验证string的数字转义为int
  • 验证int转义为string
  • 验证切片中存在多种数据类型,和数据类型不一致的转义
  • 验证map数据类型是否解析正确,和数据类型不一致的转义
  • 验证切片中包含结构体,和数据类型不一致的转义
  • 验证map中包含结构体,和数据类型不一致的转义
func TestJsonToStructMoreNest2(t *testing.T) {
	var jsonData = `
	{
		"uid": 666,
		"use_id": ["hello", 5, 9],
		"age": "20",
		"equip": {
			"keyMike": true,
			"keyTom": false
		},
		"happy": {
			"k1": [1, 2, 3],
			"k2": [4, 5, 6]
		},
		"slices": [{
			"nickname": "ABC",
			"money": "20"
		}, {
			"nickname": "EFG",
			"money": "22"
		}],
		"maps": {
			"m1": {
				"name": "alis",
				"age": "20"
			},
			"m2": {
				"name": "jom",
				"age": "22"
			}
		}
	}
	`

	type SliceVal struct {
		Nickname string `json:"nickname"`
		Money    int    `json:"money"`
	}

	type MapVal struct {
		Name string `json:"name"`
		Age  int    `json:"age"`
	}

	type Target struct {
		Uid    int               `json:"uid"`
		UseId  []string          `json:"use_id"`
		Age    int               `json:"age"`
		Equip  map[string]bool   `json:"equip"`
		Happy  map[string][]int  `json:"happy"`
		Slices []SliceVal        `json:"slices"`
		Maps   map[string]MapVal `json:"maps"`
	}

	var res Target
	err := JsonToStruct(jsonData, &res)
	if err != nil {
		t.Errorf("Unexpected error: %v", err)
	}
	//jsonRes, _ := json.Marshal(res)
	//fmt.Printf("%+v \n", res)
	//fmt.Println(string(jsonRes))

	expected := Target{
		Uid:   666,
		UseId: []string{"hello", "5", "9"},
		Age:   20,
		Equip: map[string]bool{
			"keyMike": true,
			"keyTom":  false,
		},
		Happy: map[string][]int{
			"k1": {1, 2, 3},
			"k2": {4, 5, 6},
		},
		Slices: []SliceVal{
			{
				Nickname: "ABC",
				Money:    20,
			},
			{
				Nickname: "EFG",
				Money:    22,
			},
		},
		Maps: map[string]MapVal{
			"m1": {
				Name: "alis",
				Age:  20,
			},
			"m2": {
				Name: "jom",
				Age:  22,
			},
		},
	}
	
	if !reflect.DeepEqual(res, expected) {
		t.Errorf("Result not as expected.\nExpected: %+v\nActual: %+v\n", expected, res)
	}
}