Zur Prüfung der Gleichwertigkeit von Karten in Golang?
Ich habe einen table-driven test Fall wie diesem:
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
}
}
Könnte ich prüfen, ob die Längen identisch sind, und schreiben Sie eine Schleife, die überprüft, ob alle Schlüssel-Wert-paar ist die gleiche. Aber dann habe ich, dies zu schreiben, noch einmal überprüfen, wenn ich es benutzen will, für eine andere Art von Karte (sagen map[string]string
).
Was ich am Ende tun, ist, konvertierte ich die Karten auf Streicher und den Vergleich von 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)
}
Dies setzt Voraus, dass die string-Darstellungen von gleichwertigen Karten sind die gleichen, die scheint, um wahr zu sein in diesem Fall (wenn die keys sind die gleichen, dann werden Sie hash den gleichen Wert, so dass Ihre Bestellungen werden die gleichen sein). Gibt es einen besseren Weg, dies zu tun? Was ist die idiomatische Methode zum vergleichen von zwei Karten in table-driven-tests?
- Äh, Nein: Die Reihenfolge der Iteration einer Karte nicht garantiert werden vorhersehbar: "Die iteration, um über die Karten ist nicht festgelegt und ist nicht garantiert das gleiche von einer zur nächsten iteration. ...".
- Darüber hinaus wird für Karten von bestimmten Größen Gehen wird absichtlich in zufälliger Reihenfolge. Es ist sehr ratsam, nicht davon abhängen, dass um.
- Versucht, zu vergleichen eine Karte ist ein design-Fehler in Ihrem Programm.
- Beachten Sie, dass mit go 1.12 (Feb. 2019), Karten sind jetzt gedruckt in den Schlüssel-sortiert, um Leichtigkeit Tests. Siehe meine Antwort unten
Du musst angemeldet sein, um einen Kommentar abzugeben.
Go-Bibliothek bereits hat Sie bedeckt. Tun Sie dies:
Wenn man sich die source code für
reflect.DeepEqual
'sMap
Fall, wirst du sehen, dass zuerst überprüft wird, ob beide Karten sind gleich null, dann prüft Sie, ob Sie die gleiche Länge haben, bevor Sie schließlich überprüfen, um zu sehen, wenn Sie die gleiche Menge von (Schlüssel, Wert) - Paaren.Weil
reflect.DeepEqual
nimmt ein interface-Typ ist, wird es auf keiner gültigen Karte (map[string]bool, map[struct{}]interface{}
, etc). Beachten Sie, dass es funktioniert auch auf nicht-map-Werte, also seien Sie vorsichtig, dass das, was Sie sind vorbei, es sind wirklich zwei Karten. Wenn Sie übergeben Sie zwei ganze zahlen an, es wird fröhlich erzählen Sie, ob Sie gleich sind.c.Assert(m1, DeepEquals, m2)
. Was ist schön ist, dass es bricht den test und sagt Ihnen, was Sie haben und was Sie erwartet in der Ausgabe.Dies ist, was ich tun würde (code ungetestet):
map[string]float64
.eq
funktioniert nur fürmap[string]int
Karten. Sollte ich implementieren Sie eine version deseq
- Funktion jedes mal, wenn ich vergleichen will-Instanzen eine neue Art von map?a
.Haben Sie das Projekt
go-test/deep
zu helfen.Aber: dies sollte einfacher sein, mit Gehen 1.12 (Februar 2019) nativ: Siehe release notes.
Quellen:
golang/gehen
Problem 21095,purpleidea
)CL-fügt: (CL steht für "Change-Liste")
Auch das Paket für
text/template
, die bereits eine schwächere version dieses Mechanismus.Können Sie sehen, dass in
src/fmt/drucken.go#
Haftungsausschluss: unabhängig von
map[string]int
allerdings in Bezug auf die Prüfung der Gleichwertigkeit von maps in Go, das ist der Titel der FrageWenn Sie eine Karte von einem Zeiger-Typ (wie
map[*string]int
), dann jedoch nicht verwenden möchten, zu reflektieren.DeepEqual, weil es den Wert false zurück.Schließlich, wenn der Schlüssel ist ein Typ, der enthält eine unexported Zeiger, wie die Zeit.Zeit, dann reflektieren.DeepEqual auf solch einer Karte kann auch false zurückgeben.
Inspiriert von diese Antwort, benutze ich zum testen die Gleichwertigkeit der Karten in Golang:
https://github.com/030/nexus3-cli
Verwenden Sie die "Diff" - Methode von github.com/google/go-cmp/cmp:
Code:
Ausgabe:
Eine der Optionen ist die rng-fix: