我很好奇为什么这个DeepEqual检查是错误的:
package main
import (
"encoding/json"
"fmt"
"log"
"reflect"
"strings"
)
type Result struct {
Topic string `json:"topic,omitempty"`
Id int `json:"id,omitempty"`
}
// Result represents the returned collection from a topic search.
type ResultResponse struct {
Result []Result `json:"results"`
}
func main() {
want := ResultResponse{
[]Result{{Topic: "Clojure", Id: 1000}},
}
input := `{"results": [ {"topic": "Clojure", "id": 1000} ]}`
p := ResultResponse{}
err := json.NewDecoder(strings.NewReader(input)).Decode(&p)
if err != nil {
panic(err)
}
fmt.Println(p, want)
if !reflect.DeepEqual(input, want) {
log.Printf("returned %+v, want %+v", p, want)
}
}
答案 0 :(得分:0)
我认为这是一个编辑错误。我猜你要编码的是:
"reflect.DeepEqual(p, want)"
但你实际写道:
"reflect.DeepEqual(input, want)"
答案 1 :(得分:0)
这是我的情况:
func TestGoogleAccountRepository_FindByClientCustomerIds(t *testing.T) {
type args struct {
ids []int
}
tests := []struct {
name string
args args
want []cedar.GoogleAccount
wantErr bool
}{
{
name: "should get client customer ids correctly",
args: args{ids: []int{9258066191}},
want: make([]cedar.GoogleAccount, 0),
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := googleAccountRepo.FindByClientCustomerIds(tt.args.ids)
if (err != nil) != tt.wantErr {
t.Errorf("GoogleAccountRepository.FindByClientCustomerIds() error = %v, wantErr %v", err, tt.wantErr)
return
}
fmt.Printf("got = %#v, want = %#v\n", got, tt.want)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("GoogleAccountRepository.FindByClientCustomerIds() = %+v, want %+v", got, tt.want)
}
})
}
}
第一次运行此测试时,出现以下消息:
load env vars from local fs env file
=== RUN TestGoogleAccountRepository_FindByClientCustomerIds
--- FAIL: TestGoogleAccountRepository_FindByClientCustomerIds (0.62s)
=== RUN TestGoogleAccountRepository_FindByClientCustomerIds/should_get_client_customer_ids_correctly
got = []cedar.GoogleAccount(nil), want = []cedar.GoogleAccount{}
--- FAIL: TestGoogleAccountRepository_FindByClientCustomerIds/should_get_client_customer_ids_correctly (0.62s)
googleAccount_test.go:64: GoogleAccountRepository.FindByClientCustomerIds() = [], want []
FAIL
请谨慎处理此消息:
GoogleAccountRepository.FindByClientCustomerIds() = [], want []
似乎got
和want
都是空的slice
,对吗?不,在我添加以下代码后:
fmt.Printf("got = %#v, want = %#v\n", got, tt.want)
它打印出来:
got = []cedar.GoogleAccount(nil), want = []cedar.GoogleAccount{}
如您所见,got
不等于want
。
那是因为我在googleAccounts
方法中声明了googleAccountRepo.FindByClientCustomerIds
变量,如下所示:
var googleAccounts []cedar.GoogleAccount
将其更改为
var googleAccounts = make([]cedar.GoogleAccount, 0)
测试通过:
=== RUN TestGoogleAccountRepository_FindByClientCustomerIds
--- PASS: TestGoogleAccountRepository_FindByClientCustomerIds (0.46s)
=== RUN TestGoogleAccountRepository_FindByClientCustomerIds/should_get_client_customer_ids_correctly
got = []cedar.GoogleAccount{}, want = []cedar.GoogleAccount{}
--- PASS: TestGoogleAccountRepository_FindByClientCustomerIds/should_get_client_customer_ids_correctly (0.46s)
PASS
Process finished with exit code 0
答案 2 :(得分:0)
DeepEqual 检查 2 个条件相同的类型、相同的值、
这是一个棘手的案例,考虑将值分配给 any type
(接口)例如:map[string]interface{}
大部分时间我们使用数据编码器/解码器(json)处理这些值的场景
场景一
package main
import (
"log"
"reflect"
)
func main() {
// Scenario 1
log.Print("Scenario 1")
m1 := make(map[string]interface{})
m2 := make(map[string]interface{})
m1["length"] = 1
m2["length"] = 1.0
if !reflect.DeepEqual(m1, m2) {
log.Printf("returned %+v, want %+v", m1, m2)
}
}
2009/11/10 23:00:00 返回 map[length:1],想要 map[length:1]
对于日志,这个问题将很难调试,因为除非我们检查类型,否则值看起来是一样的 (reflect.TypeOf(interface))
场景 2
package main
import (
"encoding/json"
"log"
"reflect"
"strings"
)
func main() {
// Scenario 2
log.Print("Scenario 2")
m1 := make(map[string]interface{})
m2 := make(map[string]interface{})
str1 := `{"length": "1"}`
str2 := `{"length": 1}`
json.NewDecoder(strings.NewReader(str1)).Decode(&m1)
json.NewDecoder(strings.NewReader(str2)).Decode(&m2)
if !reflect.DeepEqual(m1, m2) {
log.Printf("returned %+v, want %+v", m1, m2)
}
}
2009/11/10 23:00:00 返回 map[length:1],想要 map[length:1]
在这些动态值场景中使用 DeepEqual API 应谨慎,可能需要转换为单一数据类型或尽可能尝试使用相同的结构
答案 3 :(得分:-2)
DeepEqual
返回false,因为您正在比较两个不具有可比性的类型的实例。类型ResultResponse
无法比较,因为并非所有字段都具有可比性。 Result
字段是一个切片,切片由语言指定为不可比较。