英文:
Sqlmock is not matching the query when replace integer argument with alpha-numeric one
问题
我正在尝试使用go-sqlmock来测试我的数据库函数,但是我无法通过这个测试。
这是我的模型:
type User struct {
ID string `gorm:"primaryKey; size:11"`
FirstName string `gorm:"NOT NULL; size:255"`
LastName string `gorm:"NOT NULL; size:255"`
Email string `gorm:"NOT NULL; UNIQUE_INDEX"`
Password string `gorm:"NOT NULL"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time `sql:"index"`
}
这是我的数据库函数:
func (u *userRepo) GetByID(id string) (*user.User, AppError) {
var user user.User
if err := u.db.First(&user, id).Error; err != nil {
return nil, NewNotFoundError(err)
}
return &user, nil
}
我有两个测试示例,一个通过了,另一个没有通过。我像这样初始化了sqlmock对象:
sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
这个测试通过了:
t.Run("Get a user", func(t *testing.T) {
expected := &user.User{
Email: "alice@cc.cc",
}
u := NewUserRepo(gormDB)
mock.
ExpectQuery(
`SELECT * FROM "users" WHERE "users"."deleted_at" IS NULL AND (("users"."id" = $1)) ORDER BY "users"."id" ASC LIMIT 1`).
WithArgs("100").
WillReturnRows(
sqlmock.NewRows([]string{"email"}).
AddRow("alice@cc.cc"))
result, err := u.GetByID("100")
assert.EqualValues(t, expected, result)
assert.Nil(t, err)
})
但是这个测试没有通过:
t.Run("Get a user", func(t *testing.T) {
expected := &user.User{
Email: "alice@cc.cc",
}
u := NewUserRepo(gormDB)
mock.
ExpectQuery(
`SELECT * FROM "users" WHERE "users"."deleted_at" IS NULL AND (("users"."id" = $1)) ORDER BY "users"."id" ASC LIMIT 1`).
WithArgs("100a").
WillReturnRows(
sqlmock.NewRows([]string{"email"}).
AddRow("alice@cc.cc"))
result, err := u.GetByID("100a")
assert.EqualValues(t, expected, result)
assert.Nil(t, err)
})
你可以看到唯一的区别是我用100a
替换了100
,因为主键是一个字符串字段。
这是我得到的错误信息:
Query: actual sql:
"SELECT * FROM "users" WHERE "users"."deleted_at" IS NULL AND ((100a)) ORDER BY "users"."id" ASC LIMIT 1"
does not equal to expected
"SELECT * FROM "users" WHERE "users"."deleted_at" IS NULL AND (("users"."id" = $1)) ORDER BY "users"."id" ASC LIMIT 1"
我不知道我在这里做错了什么,我甚至将$1
替换为"$1"
也没有起作用。任何帮助将是很好的。谢谢。
英文:
I am trying to test my DB functions using go-sqlmock and I am not able make this one test pass.
Here is my model
type User struct {
ID string `gorm:"primaryKey; size:11"`
FirstName string `gorm:"NOT NULL; size:255"`
LastName string `gorm:"NOT NULL; size:255"`
Email string `gorm:"NOT NULL; UNIQUE_INDEX"`
Password string `gorm:"NOT NULL"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time `sql:"index"`
}
Here is my DB function
func (u *userRepo) GetByID(id string) (*user.User, AppError) {
var user user.User
if err := u.db.First(&user, id).Error; err != nil {
return nil, NewNotFoundError(err)
}
return &user, nil
}
I have two examples of tests, one is passing but the other does not. I am initializing sqlmock object like this
sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
This one is working
t.Run("Get a user", func(t *testing.T) {
expected := &user.User{
Email: "alice@cc.cc",
}
u := NewUserRepo(gormDB)
mock.
ExpectQuery(
`SELECT * FROM "users" WHERE "users"."deleted_at" IS NULL AND (("users"."id" = $1)) ORDER BY "users"."id" ASC LIMIT 1`).
WithArgs("100").
WillReturnRows(
sqlmock.NewRows([]string{"email"}).
AddRow("alice@cc.cc"))
result, err := u.GetByID("100")
assert.EqualValues(t, expected, result)
assert.Nil(t, err)
})
But this one is not working
t.Run("Get a user", func(t *testing.T) {
expected := &user.User{
Email: "alice@cc.cc",
}
u := NewUserRepo(gormDB)
mock.
ExpectQuery(
`SELECT * FROM "users" WHERE "users"."deleted_at" IS NULL AND (("users"."id" = $1)) ORDER BY "users"."id" ASC LIMIT 1`).
WithArgs("100a").
WillReturnRows(
sqlmock.NewRows([]string{"email"}).
AddRow("alice@cc.cc"))
result, err := u.GetByID("100a")
assert.EqualValues(t, expected, result)
assert.Nil(t, err)
})
As you can see the only difference is I replace 100
by 100a
which I can do because the primary key is a string field.
And this is the error I am getting
Query: actual sql:
"SELECT * FROM "users" WHERE "users"."deleted_at" IS NULL AND ((100a)) ORDER BY "users"."id" ASC LIMIT 1"
does not equal to expected
"SELECT * FROM "users" WHERE "users"."deleted_at" IS NULL AND (("users"."id" = $1)) ORDER BY "users"."id" ASC LIMIT 1"
I don't know what I am doing wrong here, I even replaced the $1
by "$1"
which also didn't work. Any help would be great. Thanks.
答案1
得分: 1
这个问题的解决方法如下:
首先,我更新了我的DB获取函数:
func (u *userRepo) GetByID(id string) (*user.User, AppError) {
var user user.User
if err := u.db.Where("id = ?", id).First(&user).Error; err != nil {
return nil, NewNotFoundError(err)
}
return &user, nil
}
然后,我将我的模拟测试更改为以下内容:
mock.
ExpectQuery(
`SELECT * FROM "users" WHERE "users"."deleted_at" IS NULL AND ((id = $1)) ORDER BY "users"."id" ASC LIMIT 1`).
WithArgs("100a").
WillReturnRows(
sqlmock.NewRows([]string{"email"}).
AddRow("alice@cc.cc"))
result, err := u.GetByID("100a")
英文:
Here is the fix for this issue.
First of all I update my DB get function
func (u *userRepo) GetByID(id string) (*user.User, AppError) {
var user user.User
if err := u.db.Where("id = ?", id).First(&user).Error; err != nil {
return nil, NewNotFoundError(err)
}
return &user, nil
}
And changed my mock test to this
mock.
ExpectQuery(
`SELECT * FROM "users" WHERE "users"."deleted_at" IS NULL AND ((id = $1)) ORDER BY "users"."id" ASC LIMIT 1`).
WithArgs("100a").
WillReturnRows(
sqlmock.NewRows([]string{"email"}).
AddRow("alice@cc.cc"))
result, err := u.GetByID("100a")
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论