我希望能够比较两个字典,同时忽略某些字段的值。这在Python中使用mock.ANY
非常容易。
from unittest.mock import ANY
actual = {'userName':'bob', 'lastModified':'2012-01-01'}
expected = {'userName':'bob', 'lastModified': ANY}
assert actual == expected
字符串
下面是我在Go语言中的尝试,它利用了cmp
,允许你实现一个Equal
方法(https://pkg.go.dev/github.com/google/go-cmp/cmp#Equal),但它不起作用。我相信这是因为我的MatchAll
结构体不能“赋值”给string。有什么办法可以解决这个问题吗?
package main
import (
"fmt"
"github.com/google/go-cmp/cmp"
)
type MatchAll string
func (m MatchAll) Equal(v string) bool {
return true
}
func main() {
matchAll := MatchAll("bruh")
actual := map[string]any{
"key": matchAll,
}
expected := map[string]any{
"key": "foobar",
}
fmt.Println(cmp.Equal(expected, actual))
}
型
1条答案
按热度按时间umuewwlo1#
查看
cmp
代码,我认为这里的问题在于,当比较map元素时,用于检查Equal
方法是否存在的类型是map的元素类型(这里是any
),而不是两个值之一的具体类型(这里是string
或MatchAll
)。由于any
类型没有声明Equal
方法,因此它福尔斯到内置比较。作为替代方案,您可以使用cmp.FilterValues和cmp.Comparer函数来构造一个支持特殊的“equal-to-anything”值的选项。例如,这看起来像预期的那样工作:
字符串
always-true比较函数也可以用cmp.Ignore()代替,尽管我不完全确定语义是否完全相同。至少在上面的例子中是这样的。
还有一个cmpopts.IgnoreMapEntries选项,可以按如下方式使用,但语义略有不同:
型
不同之处在于,使用此选项,即使
actual
字典根本不包含具有匹配键的条目,比较结果也将是true
,因为内置的Map比较测试是否“递归地调用Equal on * 所有未忽略的Map条目 * report equal”,重点添加。相比之下,早期的解决方案仍然需要另一个Map包含具有相同键的 some 值。