我有一个问题,我需要比较两个非常大的结构体(protobuf生成)彼此,作为测试用例的一部分。这些结构体中有多个嵌套数组。下面是一个简化的例子,重现/演示了这个问题。
package pkg
import (
"github.com/stretchr/testify/assert"
"reflect"
"testing"
)
type structOne struct {
Foo string
Offs []*structTwo
}
type structTwo struct {
Identifier string
}
func Test_Compare(t *testing.T) {
exp := &structOne{
Foo: "bar",
Offs: []*structTwo{
{
Identifier: "one",
},
{
Identifier: "two",
},
{
Identifier: "three",
},
{
Identifier: "four",
},
},
}
act := &structOne{
Foo: "bar",
Offs: []*structTwo{
{
Identifier: "four",
},
{
Identifier: "three",
},
{
Identifier: "two",
},
{
Identifier: "one",
},
},
}
assert.Equal(t, exp, act) // fails
assert.True(t, reflect.DeepEqual(exp, act)) // fails
}
我尝试过使用assert.Equal(t, exp, act)
和assert.True(t, reflect.DeepEqual(exp, act))
。我正在寻找一种方法来比较这样的结构,最好不需要为所有对象创建自定义比较函数。
谢谢你
2条答案
按热度按时间t98cgbkg1#
您可以使用
assert.ElementsMatch
来比较两个切片**,而不考虑**元素的顺序。ElementsMatchAssert指定的listA(数组,切片...)等于指定的listB(数组,切片...),忽略元素的顺序。如果有重复的元素,则它们在两个列表中出现的次数应该匹配。
但是这只适用于slice字段本身。如果你的struct模型有很少的字段,你可以逐个比较它们,然后在slice上使用
ElementsMatch
:如果你的结构体有很多字段,你可以将切片值重新分配给临时变量,
nil
字段,然后比较:如果
stretchr/testify
允许为用户定义的类型注册自定义比较器,或者检查对象是否实现了某个接口并调用该接口来测试相等性,那就更好了但我不知道有这样的功能
或者,建议使用
https://github.com/r3labs/diff
,您可以这样使用。默认情况下忽略顺序或切片项。ddrv8njm2#
你可以通过使用cmpopts包的
IgnoreFields
函数来实现这一点。你需要指定哪些结构中的哪些字段需要被忽略。名称可以是点分隔字符串(例如,
"Foo.Bar"
),以忽略嵌入或嵌套在父结构中的特定子字段。下面是一个例子: