php小編新一為您介紹Gorm刪除子句sqlmock測試。 Gorm是Go語言中優秀的ORM框架,而sqlmock是Gorm的測試工具,用來模擬資料庫操作。在進行Gorm開發時,我們經常需要進行資料庫刪除操作的測試,這時候就可以使用sqlmock來模擬資料庫的刪除操作,以便進行單元測試和整合測試。本文將為您詳細介紹如何使用Gorm和sqlmock進行刪除子句的測試,幫助您更好地進行資料庫相關的開發工作。
我有一個 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))
接收錯誤:
「使用參數[{name: ordinal:1 value:2023-01-18 06:15:34.694274 0000 utc}] 呼叫查詢'delete from "my_users" where created_at < $1 returning "email"'不是預期的,下一個期望是: expectedexec => 期望exec 或execcontext 其中:\n - 匹配sql:'delete'\n - 帶有參數:\n 0 - 2023-01-18 06:15:34.694274 0000 utc\ n - 應傳回具有以下內容的結果:\n lastinsertid: 1\n rowsaffected: 1"
我嘗試了許多其他 sqlmock 期望,但他們也有類似的問題。 另外,我們在 expectexec 中沒有回傳值,只有在 expectquery 中... 有人必須用子句測試 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("<a href="https://www.php.cn/link/89fee0513b6668e555959f5dc23238e9" class="__cf_email__" data-cfemail="9febfaecebdffae7fef2eff3fab1fcf0f2">[email protected]</a>") 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
的設置,但我認為它們應該大致相同。 expectexec
的用法切換為expectquery
,因為我們將傳回clauses
檔案中repo.go
方法指定的結果集。 expectquery
包裝在 expectbegin
和 expectcommit
中。 ?
或$1
。但在測試程式碼中,只能使用?
,否則不符合預期。 希望能幫一點忙,否則請告訴我!
以上是Gorm 刪除子句 sqlmock 測試的詳細內容。更多資訊請關注PHP中文網其他相關文章!