如何在Golang中测试地图的等效性? [英] How to test the equivalence of maps in Golang?

查看:74
本文介绍了如何在Golang中测试地图的等效性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个像这样的表驱动测试用例:

I have a table-driven test case like this one:

func CountWords(s string) map[string]int

func TestCountWords(t *testing.T) {
  var tests = []struct {
    input string
    want map[string]int
  }{
    {"foo", map[string]int{"foo":1}},
    {"foo bar foo", map[string]int{"foo":2,"bar":1}},
  }
  for i, c := range tests {
    got := CountWords(c.input)
    // TODO test whether c.want == got
  }
}

我可以检查长度是否相同,并编写一个循环来检查每个键值对是否相同.但是,当我想将其用于其他类型的地图(例如map[string]string)时,必须再次编写此检查.

I could check whether the lengths are the same and write a loop that checks if every key-value pair is the same. But then I have to write this check again when I want to use it for another type of map (say map[string]string).

我最终要做的是,我将地图转换为字符串并比较了字符串:

What I ended up doing is, I converted the maps to strings and compared the strings:

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)
}

这假定等效映射的字符串表示形式相同,在这种情况下,这似乎是正确的(如果键相同,则它们将散列为相同的值,因此其顺序将相同).有一个更好的方法吗?在表驱动测试中比较两个映射的惯用方式是什么?

This assumes that the string representations of equivalent maps are the same, which seems to be true in this case (if the keys are the same then they hash to the same value, so their orders will be the same). Is there a better way to do this? What is the idiomatic way to compare two maps in table-driven tests?

推荐答案

Go库已经覆盖了您.这样做:

The Go library has already got you covered. Do this:

import "reflect"
// m1 and m2 are the maps we want to compare
eq := reflect.DeepEqual(m1, m2)
if eq {
    fmt.Println("They're equal.")
} else {
    fmt.Println("They're unequal.")
}

如果您查看源代码对于reflect.DeepEqualMap情况,您会看到它首先检查两个映射是否均为nil,然后先检查它们是否具有相同的长度,然后才最终检查它们是否具有相同的(key,值)对.

If you look at the source code for reflect.DeepEqual's Map case, you'll see that it first checks if both maps are nil, then it checks if they have the same length before finally checking to see if they have the same set of (key, value) pairs.

因为reflect.DeepEqual采用接口类型,所以它将在任何有效的映射(map[string]bool, map[struct{}]interface{}等)上工作.请注意,它也适用于非地图值,因此请注意,传递给它的实际上是两个地图.如果您将其传递给两个整数,它将很高兴地告诉您它们是否相等.

Because reflect.DeepEqual takes an interface type, it will work on any valid map (map[string]bool, map[struct{}]interface{}, etc). Note that it will also work on non-map values, so be careful that what you're passing to it are really two maps. If you pass it two integers, it will happily tell you whether they are equal.

这篇关于如何在Golang中测试地图的等效性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆