我有一個問題,我需要將兩個非常大的結構(生成的 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))。我正在尋找一種比較此類結構的方法,最好無需為所有物件創建自定義比較函式。
謝謝
uj5u.com熱心網友回復:
無論元素順序如何,您都可以使用assert.ElementsMatch來比較兩個切片。
ElementsMatch 斷言指定的 listA(array, slice...) 等于指定的 listB(array, slice...) 忽略元素的順序。如果有重復的元素,它們在兩個串列中的出現次數應該匹配。
然而,這僅適用于切片欄位本身。如果你的 struct 模型的欄位很少,你可以將它們一一比較并ElementsMatch在切片上使用:
assert.Equal(t, exp.Foo, act.Foo)
assert.ElementsMatch(t, exp.Offs, act.Offs)
如果您的結構有很多欄位,您可以將切片值重新分配給臨時變數,nil將欄位取出,然后進行比較:
expOffs := exp.Offs
actOffs := act.Offs
exp.Offs = nil
act.Offs = nil
assert.Equal(t, exp, act) // comparing full structs without Offs
assert.ElementsMatch(t, expOffs, actOffs) // comparing Offs separately
如果stretchr/testify允許為用戶定義的型別注冊自定義比較器,或者檢查物件是否實作某個介面并呼叫它來測驗相等性,那就更好了
if cmp, ok := listA.(Comparator); ok {
cmp.Compare(listB)
}
但我不知道這樣的功能。
或者,https://github.com/r3labs/diff有人建議,你可以這樣使用。默認情況下會忽略訂單或切片專案。
// import "github.com/r3labs/diff/v2"
changelog, err := diff.Diff(exp, act)
assert.NoError(t, err)
assert.Len(t, changelog, 0)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/358286.html
上一篇:如何從go中的大json獲取資料
