package user import ( "encoding/json" "sync" "testing" "yunyan/pb" "gorm.io/gorm/schema" ) // 老包按「非空 int」解析 factoryid,缺字段整个响应就解析不了。这里固化两件事: // 值等于 brandid,且 brandid=0 时也要输出 0(不能被 omitempty 吃掉变成 null)。 func TestCompatProductFillsFactoryid(t *testing.T) { cases := []struct { name string brandid uint32 }{ {"正常品牌商", 40981}, {"无品牌归属:仍要输出 0,不能缺字段", 0}, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { p := compatProduct(&pb.DBProduct{Id: 45107, Brandid: c.brandid}) if p.Factoryid != c.brandid { t.Fatalf("factoryid=%d,期望等于 brandid=%d", p.Factoryid, c.brandid) } buf, err := json.Marshal(p) if err != nil { t.Fatal(err) } var got map[string]any if err = json.Unmarshal(buf, &got); err != nil { t.Fatal(err) } v, ok := got["factoryid"] if !ok || v == nil { t.Fatalf("下发 JSON 缺 factoryid(老客户端会 TypeError):%s", buf) } if v.(float64) != float64(c.brandid) { t.Fatalf("下发 factoryid=%v,期望 %d", v, c.brandid) } }) } } func TestCompatProductsNilSafe(t *testing.T) { if compatProduct(nil) != nil { t.Fatal("nil 入参不应造出对象") } compatProducts([]*pb.DBProduct{nil, {Brandid: 7}}) // 不能 panic } // factoryid 是纯下发字段:gorm 必须完全忽略它,否则 AutoMigrate 会给产品表建一个恒为 0 的多余列。 func TestFactoryidNotPersisted(t *testing.T) { s, err := schema.Parse(&pb.DBProduct{}, &sync.Map{}, schema.NamingStrategy{}) if err != nil { t.Fatal(err) } if f := s.LookUpField("factoryid"); f != nil { t.Fatalf("factoryid 被 gorm 当成了库字段(列 %s),应由 gorm:\"-\" 忽略", f.DBName) } if s.LookUpField("brandid") == nil { t.Fatal("brandid 应该是库字段,测试基准不成立") } }