[英]Gorm delete with clauses sqlmock test
我有一個帶有返回結果的 Gorm 刪除:
expirationDate := time.Now().UTC().Add(-(48 * time.hour))
var deletedUsers Users
res := gormDB.WithContext(ctx).
Table("my_users").
Clauses(clause.Returning{Columns: []clause.Column{{Name: "email"}}}).
Where("created_at < ?", expirationDate).
Delete(&deletedUsers)
現在帶有子句的測試總是失敗。 例如:
sqlMock.ExpectExec(`DELETE`)
.WithArgs(expirationDate)
.WillReturnResult(sqlmock.NewResult(1, 1))
接收錯誤:
“使用 args [{Name: Ordinal:1 Value:2023-01-18 06:15:34.694274 +0000 UTC}] 調用查詢‘DELETE FROM “my_users” WHERE created_at < $1 RETURNING “email”’,這不是預期的,下一個期望是:ExpectedExec => expecting Exec or ExecContext which:\n - matches sql: 'DELETE'\n - is with arguments:\n 0 - 2023-01-18 06:15:34.694274 +0000 UTC\n - should返回結果有:\n LastInsertId: 1\n RowsAffected: 1"
我嘗試了許多其他 sqlMock 期望,但它們有類似的問題。 此外,我們在 ExpectExec 中沒有返回值,只有在 ExpectQuery 中......是否有人必須使用 Clauses 測試 Gorm 查詢?
我能夠成功地管理你所需要的。 首先,讓我分享我編寫的文件,然后我將向您介紹所有相關更改。 這些文件是用於生產的repo.go
和用於測試代碼的repo_test.go
。
repo.go
package gormdelete
import (
"context"
"time"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
type Users struct {
Email string
}
func Delete(ctx context.Context, gormDB *gorm.DB) error {
expirationDate := time.Now().UTC().Add(-(48 * time.Hour))
var deletedUsers Users
res := gormDB.WithContext(ctx).Table("my_users").Clauses(clause.Returning{Columns: []clause.Column{{Name: "email"}}}).Where("created_at < ?", expirationDate).Delete(&deletedUsers)
if res.Error != nil {
return res.Error
}
return nil
}
由於您沒有提供完整的文件,我試圖猜測缺少了什么。
repo_test.go
package gormdelete
import (
"context"
"database/sql/driver"
"testing"
"time"
"github.com/DATA-DOG/go-sqlmock"
"github.com/stretchr/testify/assert"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
// this is taken directly from the docs
// https://github.com/DATA-DOG/go-sqlmock#matching-arguments-like-timetime
type AnyTime struct{}
// Match satisfies sqlmock.Argument interface
func (a AnyTime) Match(v driver.Value) bool {
_, ok := v.(time.Time)
return ok
}
func TestDelete(t *testing.T) {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error was not expected: %v", err)
}
conn, _ := db.Conn(context.Background())
gormDb, err := gorm.Open(postgres.New(postgres.Config{
Conn: conn,
}))
row := sqlmock.NewRows([]string{"email"}).AddRow("test@example.com")
mock.ExpectBegin()
mock.ExpectQuery("DELETE FROM \"my_users\" WHERE created_at < ?").WithArgs(AnyTime{}).WillReturnRows(row)
mock.ExpectCommit()
err = Delete(context.Background(), gormDb)
assert.Nil(t, err)
if err = mock.ExpectationsWereMet(); err != nil {
t.Errorf("not all expectations were met: %v", err)
}
}
在這里,還有更多值得一提的變化:
AnyTime
(您可以在評論中看到鏈接)。db
、 mock
和gormDb
的設置,但我認為它們應該或多或少是相同的。ExpectQuery
ExpectExec
因為我們將返回repo.go
文件中的Clauses
方法指定的結果集。ExpectQuery
包裝在ExpectBegin
和ExpectCommit
中。?
或$1
。 但是,在測試代碼中,您只能使用?
否則它將不符合預期。希望能幫上一點忙,否則,請告訴我!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.