php editor Xinyi introduces to you the Gorm delete clause sqlmock test. Gorm is an excellent ORM framework in the Go language, and sqlmock is a testing tool for Gorm, used to simulate database operations. When developing Gorm, we often need to test the database deletion operation. At this time, we can use sqlmock to simulate the database deletion operation for unit testing and integration testing. This article will introduce you in detail how to use Gorm and sqlmock to test delete clauses, helping you better carry out database-related development work.
I have a gorm deleted and the result is returned:
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)
Tests with clauses now always fail. For example:
sqlMock.ExpectExec(`DELETE`) .WithArgs(expirationDate) .WillReturnResult(sqlmock.NewResult(1, 1))
Receive error:
'Calling query 'delete from "my_users" where created_at < $1 returning "email"' with parameters [{name: ordinal:1 value:2023-01-18 06:15:34.694274 0000 utc}] is not expected , the next expectation is: expectedexec => expected exec or execcontext where:\n - matches sql: 'delete'\n - with parameters:\n 0 - 2023-01-18 06:15:34.694274 0000 utc\n - should return results with:\n lastinsertid: 1\n rowsaffected: 1"
I tried many other sqlmock expectations but they had similar issues. Also, we have no return value in expectexec, only in expectquery... Does anyone have to test gorm queries with clauses?
I was able to successfully manage your needs. First, let me share the file I wrote, and then I'll walk you through all the relevant changes. These files are repo.go
for production and repo_test.go
for test code.
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 }
Since you didn't provide the complete file, I tried to guess what is missing.
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) } }
Here are more changes worth mentioning:
anytime
according to the documentation (you can see the link in the comments). db
, mock
and gormdb
, but I think they should be roughly the same. expectexec
to expectquery
because we will return the results specified by the repo.go
method in the clauses
file set. expectquery
in expectbegin
and expectcommit
. ?
or $1
. But in the test code, you can only use ?
, otherwise it will not meet expectations. Hope it can be of some help, otherwise please let me know!
The above is the detailed content of Gorm delete clause sqlmock test. For more information, please follow other related articles on the PHP Chinese website!