Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test the equivalence of maps in 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   } } 

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?

like image 938
andras Avatar asked Aug 13 '13 11:08

andras


People also ask

How do I compare maps in go?

In Go language, you are allowed to compare two maps with each other using DeepEqual() function provided by the reflect package. This function returns true if both the maps satisfy the following conditions: Both maps are nil or non-nil. Both maps have the same length.

How do I compare structs in Golang?

In Go language, you are allowed to compare two structures if they are of the same type and contain the same fields values with the help of == operator or DeeplyEqual() Method.

How do you check if a key exists in a map in go?

To check if specific key is present in a given map in Go programming, access the value for the key in map using map[key] expression. This expression returns the value if present, and a boolean value representing if the key is present or not.


1 Answers

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

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.

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.

like image 175
joshlf Avatar answered Sep 19 '22 00:09

joshlf