回答

收藏

如何在 Golang 中测试map的等价性?

技术问答 技术问答 205 人阅读 | 0 人回复 | 2023-09-12

我有一个像这样的表驱动测试用例:
9 c2 w, G2 h- ]  L4 u. r* l( w

    + q- R" o2 A' q* S; \' }3 Q5 f, y5 C
  • func CountWords(s string) map[string]intfunc TestCountWords(t *testing.T) {  var tests = []struct    input string    want map[string]int {     {"foo",map[string]int{"foo":},   {"foo bar foo",map[string]int{"foo":2,"bar":}, }  for i,c := range tests    got := CountWords(c.input)    // TODO test whether c.want == got }code]我可以检查长度是否相同,并编写一个循环来检查每个键值是否相同。然而,当我想在另一种类型的地图上使用它时(例如map[string]string)我必须再次编写这个检查。
    2 E) v7 O& _: J& G# G1 ?- b
  • 我最终做的是,我将地图转换为字符串并比较字符串:[code]func checkAsStrings(a,b interface{}) bool {  return fmt.Sprintf("%v",a) != fmt.Sprintf("%v",b) }//...if checkAsStrings(got,c.want) {  t.Errorf("Case #%v: Wanted: %v,got: %v",i,c.want,got)}% F' n9 {/ d+ q2 n
假设等效映射的字符串是相同的,在这种情况下似乎是正确的(如果键是相同的,它们会分散到相同的值,因此它们的顺序将是相同的)。有更好的方法吗?在表驱动测试中比较两张地图的常用方法是什么?
& \) {# m7 ]3 c                                                                2 D2 ~# k. C' Z, M% p" @* j
    解决方案:                                                               
8 x2 f( l1 F# k1 N                                                                Go 库已经覆盖了你。这样做:. A, h7 D3 {8 x8 G2 a. Q
    import "reflect"// m1 and m2 are the maps we want to compareeq := reflect.DeepEqual(m1,m2)if eq    fmt.Println("They're equal.")} else    fmt.Println("They're unequal.")}' Y" d% n6 Z7 n7 ~  u, g# k. x4 ], i
如果您查看源代码供应reflect.DeepEqual的Map在这种情况下,你会发现,如果这两张地图的第一次检查是零,那么在检查之前,他们有相同的长度,看看他们是否有相同的组(键,值)是正确的。. @/ R8 G: y; z$ b7 U6 L: O! \% w$ a; y
因为reflect.DeepEqual它需要一个接口类型,所以它可以在任何有效的地图上工作(map[string]bool,map[struct{}]interface{}等等。请注意,它也适用于非地图值,所以请注意,你传递给它的实际上是两张地图。如果你传递两个整数,它会很高兴告诉你它们是否相等。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则