我正在努力使用 sqlmock 和 gorm 為我的 go lambda 函數編寫測試。
這是我要測試的功能:
func docleanup(con *gorm.db) { sixmonthsago := time.now().adddate(0, -6, 0).format("2006-02-01") con.where("date_to <= ?", sixmonthsago).delete(&availability{}) con.where("date_to <= ?", sixmonthsago).delete(&reservation{}) }
這是我的測試:
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() mock.expectquery(fmt.sprintf("delete from availability where date_to <= '%s'", time.now().adddate(0, -6, 0).format("2006-02-01"))) mock.expectquery(fmt.sprintf("delete from reservations where date_to <= '%s'", time.now().adddate(0, -6, 0).format("2006-02-01"))) docleanup(conn) err = mock.expectationsweremet() assert.nil(m, err) }
我不知道我做錯了什麼。這是我第一次使用 sqlmock。我已經閱讀了一些地方,我的程式碼看起來不錯,但我沒有得到結果。我的錯誤是:
Expected nil, but got: &errors.errorString{s:"there is a remaining expectation which was not matched: ExpectedQuery => expecting Query, QueryContext or QueryRow which:\n - matches sql: 'DELETE FROM availability WHERE date_to <= '2022-13-06''\n - is without arguments"}
知道我做錯了什麼嗎?
我看到的主要問題在於您期望查詢的方式。而不是
mock.expectquery(fmt.sprintf("delete from availability where date_to <= '%s'", time.now().adddate(0, -6, 0).format("2006-02-01")))
你應該有:
mock.expectbegin() mock.expectexec("delete from `availability` where date_to <= ?"). withargs(time.now().adddate(0, -6, 0).format("2006-02-01")). willreturnresult(sqlmock.newresult(0, 0)) mock.expectcommit()
這將告訴模擬您正在使用事務(expectbegin
和expectcommit
圍繞刪除),查詢是使用參數進行的(withargs
),以及查詢的回傳結果是什麼(willreturnresult
)
還有一些其他的細微變化,例如表名周圍的``(mysql 習慣用法)和表名(gorm 通常會將名稱複數,因此您要么在availability
上實現 tablename
,要么預設為可用性)。
查看所有這些問題的最佳方法是更改 docleanup
以傳回錯誤,然後在測試中查看它們:
func docleanup(con *gorm.db) error { sixmonthsago := time.now().adddate(0, -6, 0).format("2006-02-01") tx := con.where("date_to <= ?", sixmonthsago).delete(&availability{}) if tx.error != nil { return tx.error } tx = con.where("date_to <= ?", sixmonthsago).delete(&reservation{}) if tx.error != nil { return tx.error } return nil } ... err = docleanup(conn) assert.nil(m, err) ...
這樣做,並使用當前的程式碼,您將得到
Expected nil, but got: &errors.errorString{s:"call to database transaction Begin, was not expected, next expectation is: ExpectedQuery => expecting Query, QueryContext or QueryRow which:\n - matches sql: 'DELETE FROM availability WHERE date_to <= '2022-13-06''\n - is without arguments"}
這告訴您 sqlmock 不期望 begin,解決該問題後您將得到本答案第一部分中解決的其他錯誤。
以上是使用 gorm 和 sqlmock 進行測試的詳細內容。更多資訊請關注PHP中文網其他相關文章!