You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Gorm与Sqlmock测试Go Lambda函数时的报错问题排查

问题原因及修复方案

1. 错误使用ExpectQuery处理DELETE操作

DELETE属于数据库写操作,sqlmock中需用ExpectExec而非ExpectQuery——ExpectQuery仅适用于SELECT类查询语句,这是导致预期不匹配的核心原因之一。

2. 时间格式字符串错误

Go的时间格式化基于参考时间Mon Jan 2 15:04:05 MST 2006,你写的"2006-02-01"实际对应年-日-月,这会导致月份被解析为日期数字,出现2022-13-06这种非法月份的错误。正确的年-月-日格式应为"2006-01-02"。

3. 表名与GORM默认生成规则不符

GORM默认将结构体名转为复数下划线格式:

  • Availability对应的默认表名是availabilities(而非你测试中写的availability)
  • Reservation对应的默认表名是reservations(此部分正确)
    若你的结构体未自定义表名,需修正测试中的表名匹配规则。

4. 直接拼接SQL字符串的风险

不要直接将时间字符串拼接到SQL中,应使用参数化匹配,避免测试运行时的时间差导致匹配失败。


修复后的测试代码

func TestDoCleanup(m *testing.T) {
    var mock sqlmock.Sqlmock
    var db *sql.DB
    var err error

    db, mock, err = sqlmock.New()
    assert.Nil(m, err)

    dialector := mysql.New(mysql.Config{
        DSN:                       "sqlmock_db_0",
        DriverName:                "mysql",
        Conn:                      db,
        SkipInitializeWithVersion: true,
    })

    conn, err := gorm.Open(dialector, &gorm.Config{})
    if err != nil {
        m.Errorf("Failed to open connection to DB: %v", err)
    }

    if conn == nil {
        m.Error("Failed to open connection to DB: conn is nil")
    }

    defer db.Close()

    sixMonthsAgo := time.Now().AddDate(0, -6, 0).Format("2006-01-02")
    
    // 用ExpectExec匹配DELETE操作,使用参数化校验
    mock.ExpectExec("DELETE FROM availabilities WHERE date_to <= ?").
        WithArgs(sixMonthsAgo).
        WillReturnResult(sqlmock.NewResult(0, 0))
    
    mock.ExpectExec("DELETE FROM reservations WHERE date_to <= ?").
        WithArgs(sixMonthsAgo).
        WillReturnResult(sqlmock.NewResult(0, 0))

    DoCleanup(conn)

    err = mock.ExpectationsWereMet()
    assert.Nil(m, err)
}

同步修正原函数的时间格式错误

原函数中的时间格式同样错误,需同步修改:

func DoCleanup(con *gorm.DB) {
    // 修正为正确的年-月-日格式
    sixMonthsAgo := time.Now().AddDate(0, -6, 0).Format("2006-01-02")
    con.Where("date_to <= ?", sixMonthsAgo).Delete(&Availability{})
    con.Where("date_to <= ?", sixMonthsAgo).Delete(&Reservation{})
}

内容的提问来源于stack exchange,提问作者Bird87 ZA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 12:10:31