package repository import ( "database/sql" "errors" "reflect" "strings" "testing" "cmautobuy/admin/model" ) type aiConfigCaptureExecer struct { query string args []any } func (c *aiConfigCaptureExecer) Exec(query string, args ...any) (sql.Result, error) { c.query = query c.args = append([]any(nil), args...) return aiConfigResult(1), nil } func (c *aiConfigCaptureExecer) Query(string, ...any) (*sql.Rows, error) { return nil, errors.New("本测试不应执行 Query") } func (c *aiConfigCaptureExecer) QueryRow(string, ...any) *sql.Row { panic("本测试不应执行 QueryRow") } type aiConfigResult int64 func (r aiConfigResult) LastInsertId() (int64, error) { return int64(r), nil } func (r aiConfigResult) RowsAffected() (int64, error) { return int64(r), nil } func TestInsertAIProvider_占位符与字段参数一一对应(t *testing.T) { item := model.AIProviderConfig{ ProviderID: "AIP-1", Name: "主线路", BaseURL: "https://api.example.com/v1", Model: "model-1", TimeoutSeconds: 30, MaxConcurrency: 2, ConfidenceThresholdBPS: 8500, CreatedByUserID: "USR-CREATE", UpdatedByUserID: "USR-UPDATE", CreatedAt: "2026-08-14T00:00:00Z", UpdatedAt: "2026-08-14T00:01:00Z", } capture := &aiConfigCaptureExecer{} if err := InsertAIProvider(capture, item); err != nil { t.Fatal(err) } if got, want := strings.Count(capture.query, "?"), len(capture.args); got != want { t.Fatalf("INSERT 占位符=%d,参数=%d;两者必须相同", got, want) } wantArgs := []any{item.ProviderID, item.Name, item.BaseURL, item.Model, item.TimeoutSeconds, item.MaxConcurrency, item.ConfidenceThresholdBPS, item.CreatedByUserID, item.UpdatedByUserID, item.CreatedAt, item.UpdatedAt} if !reflect.DeepEqual(capture.args, wantArgs) { t.Fatalf("INSERT 参数顺序错误\n实际: %#v\n期望: %#v", capture.args, wantArgs) } for _, fixed := range []string{"0", "'pending'"} { if !strings.Contains(capture.query, fixed) { t.Fatalf("INSERT 缺少固定初始值 %s", fixed) } } }