[英]Compare structs that have slice fields ignoring item order with stretchr/testify
我有一個問題,我需要將兩個非常大的結構(生成的 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))
。 我正在尋找一種比較此類結構的方法,最好無需為所有對象創建自定義比較函數。
謝謝
嘗試檢查這個https://github.com/r3labs/diff
它也應該有助於將結構與自定義類型進行比較!
無論元素順序如何,您都可以使用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
然后我可以斷言更改列表為空。 今天早些時候的一個用戶提供了這個作為有效的答案,但在我回復之前用戶刪除了答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.