golang验证JSON序列化正确性的测试插件库jsonassert的使用
Golang验证JSON序列化正确性的测试插件库jsonassert的使用
介绍
使用Go内置的测试包很难确认JSON负载(如HTTP请求或响应体)是否符合预期。jsonassert
是一个易于使用的Go测试断言库,用于验证两个JSON表示在语义上是否相等。
使用方法
在测试中创建一个新的*jsonassert.Asserter
,并用它来对JSON负载进行断言:
func TestWhatever(t *testing.T) {
ja := jsonassert.New(t)
// 查找某种负载
name := "River Tam"
age := 16
ja.Assertf(payload, `
{
"name": "%s",
"age": %d,
"averageTestScore": "%s",
"skills": [
{ "name": "martial arts", "level": 99 },
{ "name": "intelligence", "level": 100 },
{ "name": "mental fortitude", "level": 4 }
]
}`, name, age, "99%")
}
你可以在预期的JSON结构后传入fmt.Sprintf
参数。当你的测试中已经有包含预期数据的变量,或者当你的预期JSON包含可能被误解为格式指令的%
字符时,这个特性可能很有用。
ja.Assertf()
仅支持对字符串的断言。
仅检查存在性
JSON负载的某些属性可能难以提前知道,例如时间戳、UUID或其他随机分配的值。
对于这些类型的值,使用字符串"<<PRESENCE>>"
作为预期值,jsonassert
将仅验证该键是否存在(即实际的JSON具有预期的键,并且其值不为null
),但不会检查其值。
例如:
func TestWhatever(t *testing.T) {
ja := jsonassert.New(t)
ja.Assertf(`
{
"time": "2019-01-28T21:19:42",
"uuid": "94ae1a31-63b2-4a55-a478-47764b60c56b"
}`, `
{
"time": "<<PRESENCE>>",
"uuid": "<<PRESENCE>>"
}`)
}
上面的测试会通过,但:
func TestWhatever(t *testing.T) {
ja := jsonassert.New(t)
ja.Assertf(`
{
"date": "2019-01-28T21:19:42",
"uuid": null
}`, `
{
"time": "<<PRESENCE>>",
"uuid": "<<PRESENCE>>"
}`)
}
上面的测试会失败,因为实际的JSON中没有time
键,且uuid
为null
。
忽略数组中的顺序
如果你的JSON负载包含一个数组,其元素的顺序不是确定性的,那么你可以在数组的第一个元素中使用"<<UNORDERED>>"
指令:
func TestUnorderedArray(t *testing.T) {
ja := jsonassert.New(t)
payload := `["bar", "foo", "baz"]`
ja.Assertf(payload, `["foo", "bar", "baz"]`) // 顺序重要,会使测试失败
ja.Assertf(payload, `["<<UNORDERED>>", "foo", "bar", "baz"]`) // 顺序无关,会使测试通过
}
文档
你可以在GoDocs中找到这个包的文档。
贡献
欢迎贡献。请在提交PR之前阅读贡献指南并在issue中讨论功能请求。
更多关于golang验证JSON序列化正确性的测试插件库jsonassert的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang验证JSON序列化正确性的测试插件库jsonassert的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang中使用jsonassert验证JSON序列化正确性
jsonassert是一个用于测试JSON序列化正确性的Go测试库,它可以帮助你验证生成的JSON是否符合预期结构,包括字段名称、值和类型。
安装
go get github.com/kinbiko/jsonassert
基本用法
1. 简单验证
package main
import (
"testing"
"github.com/kinbiko/jsonassert"
)
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
func TestPersonJSON(t *testing.T) {
ja := jsonassert.New(t)
p := Person{Name: "Alice", Age: 30}
expected := `{"name": "Alice", "age": 30}`
// 将结构体序列化为JSON字符串
actual, err := json.Marshal(p)
if err != nil {
t.Fatalf("Failed to marshal: %v", err)
}
ja.Assertf(string(actual), expected)
}
2. 验证可选字段
func TestOptionalFields(t *testing.T) {
ja := jsonassert.New(t)
// 使用"<present>"表示字段必须存在但不关心具体值
ja.Assertf(
`{"name": "Bob", "age": 25, "email": "bob@example.com"}`,
`{"name": "<present>", "age": 25, "email": "<present>"}`,
)
}
3. 正则表达式匹配
func TestRegexMatching(t *testing.T) {
ja := jsonassert.New(t)
// 使用正则表达式验证字段值格式
ja.Assertf(
`{"id": "user-12345", "created_at": "2023-01-01T12:00:00Z"}`,
`{
"id": "<<PRESENCE>>",
"created_at": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$"
}`,
)
}
4. 数组验证
func TestArrayValidation(t *testing.T) {
ja := jsonassert.New(t)
// 验证数组内容和顺序
ja.Assertf(
`{"items": [1, 2, 3]}`,
`{"items": [1, 2, 3]}`,
)
// 只验证数组长度
ja.Assertf(
`{"items": [1, 2, 3]}`,
`{"items": "<<PRESENCE>>"}`,
)
}
5. 嵌套结构验证
type Address struct {
Street string `json:"street"`
City string `json:"city"`
}
type User struct {
Name string `json:"name"`
Address Address `json:"address"`
}
func TestNestedStruct(t *testing.T) {
ja := jsonassert.New(t)
user := User{
Name: "Charlie",
Address: Address{
Street: "123 Main St",
City: "New York",
},
}
expected := `{
"name": "Charlie",
"address": {
"street": "123 Main St",
"city": "New York"
}
}`
actual, _ := json.Marshal(user)
ja.Assertf(string(actual), expected)
}
高级特性
1. 忽略某些字段
func TestIgnoreFields(t *testing.T) {
ja := jsonassert.New(t)
// 使用"<<IGNORE>>"忽略特定字段
ja.Assertf(
`{"id": "123", "name": "Dave", "timestamp": "2023-01-01"}`,
`{
"id": "<<IGNORE>>",
"name": "Dave",
"timestamp": "<<IGNORE>>"
}`,
)
}
2. 自定义比较器
func TestCustomComparator(t *testing.T) {
ja := jsonassert.New(t)
// 为特定字段定义自定义比较逻辑
ja.AssertfWithOptions(
`{"score": 95.12345}`,
`{"score": 95.12}`,
jsonassert.Options{
FloatPrecision: 2, // 只比较小数点后两位
},
)
}
最佳实践
- 保持测试简洁:只验证必要的字段,使用
<<PRESENCE>>
或<<IGNORE>>
简化测试 - 优先验证结构:类型和字段名称比具体值更重要
- 处理动态数据:对时间戳、ID等动态生成的数据使用正则或忽略
- 组合使用:可以结合标准库的
json.Unmarshal
和jsonassert
进行更全面的测试
jsonassert是一个强大的工具,可以显著简化JSON序列化的测试工作,同时保持测试的准确性和可维护性。