答案是测试Go中JSON序列化与反序列化需使用encoding/json和testing包,定义结构体并验证Marshal和Unmarshal结果。1. 定义带json标签的结构体如Person{Name, Age},编写TestJSONMarshalUnmarshal函数:先将Person实例序列化为JSON字符串,比对输出是否符合预期;再反序列化到新变量,用reflect.DeepEqual检查数据一致性。2. 测试嵌套结构与指针字段,定义含Address、User等复杂类型,覆盖omitempty标签场景,构造非nil和nil值组合,验证字段正确编解码。3. 验证错误输入,传入类型不匹配的JSON(如age为字符串),确保Unmarshal返回错误。4. 使用表驱动测试提升覆盖率,遍历多个用例(正常数据、零值等),分别执行Marshal并比对结果。5. 注意nil指针、空切片、null处理等边界情况,确保程序健壮性。核心是结合反射、错误处理和多种测试用例,保障结构体与JSON准确转换。

测试 Go 中的 JSON 序列化与反序列化,关键在于验证结构体能否正确地转换为 JSON 字符串,以及从 JSON 字符串还原为结构体。主要使用 encoding/json 包配合 testing 包来完成。
定义结构体并编写基础测试
先定义一个简单的结构体,并使用 JSON 标签。然后编写测试函数,验证序列化和反序列化的结果是否符合预期。
package mainimport ( "encoding/json" "reflect" "testing")type Person struct { Name string `json:"name"` Age int `json:"age"`}func TestJSONMarshalUnmarshal(t *testing.T) { p := Person{Name: "Alice", Age: 25} // 序列化 data, err := json.Marshal(p) if err != nil { t.Fatalf("序列化失败: %v", err) } expected := `{"name":"Alice","age":25}` if string(data) != expected { t.Errorf("序列化结果不符: 得到 %s, 期望 %s", data, expected) } // 反序列化 var p2 Person if err := json.Unmarshal(data, &p2); err != nil { t.Fatalf("反序列化失败: %v", err) } if !reflect.DeepEqual(p, p2) { t.Errorf("反序列化后数据不一致: %v ≠ %v", p, p2) }}
测试嵌套结构与指针字段
复杂结构如嵌套结构体、指针或切片也需要覆盖。注意 nil 值在 JSON 中的表现。
type Address struct { City string `json:"city"` Zip string `json:"zip,omitempty"`}type User struct { Person Email *string `json:"email,omitempty"` Address *Address `json:"address,omitempty"` Tags []string `json:"tags,omitempty"`}
测试时构造包含 nil 和非 nil 的情况:
立即学习“go语言免费学习笔记(深入)”;
func TestNestedStructJSON(t *testing.T) { email := "bob@example.com" addr := &Address{City: "Beijing"} u := User{ Person: Person{Name: "Bob", Age: 30}, Email: &email, Address: addr, Tags: []string{"dev", "go"}, } data, err := json.Marshal(u) if err != nil { t.Fatal(err) } var u2 User if err := json.Unmarshal(data, &u2); err != nil { t.Fatal(err) } if u2.Name != u.Name || u2.Age != u.Age { t.Error("基本字段丢失") } if u2.Email == nil || *u2.Email != *u.Email { t.Error("Email 不一致") } if u2.Address.City != addr.City { t.Error("地址信息错误") }}
测试错误输入与边界情况
验证非法 JSON 是否能被正确捕获,比如格式错误或类型不匹配。
func TestInvalidJSON(t *testing.T) { invalidJSON := `{"name":"Alice","age":"not_a_number"}` var p Person err := json.Unmarshal([]byte(invalidJSON), &p) if err == nil { t.Fatal("应返回错误,但未报错") }}
还可测试空值、null 处理等特殊情况。
使用表驱动测试提升覆盖率
用表驱动方式批量测试多种输入,代码更清晰,维护方便。
func TestPerson_Marshal(t *testing.T) { tests := []struct { name string input Person expected string }{ {"正常数据", Person{Name: "Tom", Age: 20}, `{"name":"Tom","age":20}`}, {"零值", Person{}, `{"name":"","age":0}`}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { data, _ := json.Marshal(tt.input) if string(data) != tt.expected { t.Errorf("期望 %s, 得到 %s", tt.expected, data) } }) }}
基本上就这些。核心是构造典型数据,正向验证序列化输出,反向确认能还原。结合反射和错误处理,确保结构稳定可靠。不复杂但容易忽略细节。
以上就是Golang如何测试JSON序列化与反序列化的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1413932.html
微信扫一扫
支付宝扫一扫