testing - 带有gorm INSERT的sqlmock
问题描述
我在模拟 gorm INSERT 查询时遇到了很多麻烦。选择正常时我能够通过测试,但插入时遇到此错误。
# gorms's debug output
INSERT INTO "groups" ("created_at","updated_at","deleted_at","name","description") VALUES ('2018-05-01 17:46:15','2018-05-01 17:46:15',NULL,'Group 1','A good group') RETURNING "groups"."id"
# Error returned from *gorm.DB.Create
2018/05/01 17:46:15 Error creating group: call to Query 'INSERT INTO "groups" ("created_at","updated_at","deleted_at","name","description") VALUES ($1,$2,$3,$4,$5) RETURNING "groups"."id"' with args [{Name: Ordinal:1 Value:2018-05-01 17:46:15.384319544 -0700 PDT m=+0.005382104} {Name: Ordinal:2 Value:2018-05-01 17:46:15.384319544 -0700 PDT m=+0.005382104} {Name: Ordinal:3 Value:<nil>} {Name: Ordinal:4 Value:Group 1} {Name: Ordinal:5 Value:A good group}], was not expected, next expectation is: ExpectedExec => expecting Exec or ExecContext which:
- matches sql: '^INSERT INTO "groups" (.+)$'
- is with arguments:
0 - {}
1 - {}
2 - <nil>
3 - Group 1
4 - A good group
- should return Result having:
LastInsertId: 1
RowsAffected: 1
我尝试了多个不同版本的正则表达式,甚至在 regex101.com 上使用 golang 测试了匹配,但我似乎无法让我的 sqlmock 匹配 gorm 的插入。
这是我的测试:
type AnyTime struct{} // I don't actually know if I even need this
func (a AnyTime) Match(v driver.Value) bool {
_, ok := v.(time.Time)
return ok
}
func TestGroupService_Create(t *testing.T) {
db, mock, err := sqlmock.New()
if err != nil {
log.Fatalf("can't create sqlmock: %s", err)
}
models.DB, err = gorm.Open("postgres", db)
if err != nil {
log.Fatalf("can't open gorm connection: %s", err)
}
defer db.Close()
models.DB.LogMode(true)
name := "Group 1"
description := "A good group"
mock.ExpectExec("^INSERT INTO \"groups\" (.+)$").WithArgs(AnyTime{}, AnyTime{}, nil, name, description).WillReturnResult(sqlmock.NewResult(1, 1))
s := GroupService{}
req := &pb.CreateGroupRequest{
Name: name,
Description: description,
}
resp, err := s.Create(context.Background(), req)
assert.Nil(t, err)
if assert.NotNil(t, resp) {
assert.Equal(t, resp.Group.Name, name)
assert.Equal(t, resp.Group.Description, description)
}
err = mock.ExpectationsWereMet()
assert.Nil(t, err)
}
以及我正在尝试测试的服务方法:
func (server *GroupService) Create(ctx context.Context, request *pb.CreateGroupRequest) (*pb.CreateGroupReply, error) {
var group models.Group
group.Name = request.Name
group.Description = request.Description
db := models.DB
if err := db.Create(&group).Error; err != nil {
log.Printf("Error creating group: %v", err)
return nil, err
}
createReply := pb.CreateGroupReply{
Group: mapGroupToService(group),
}
return &createReply, nil
}
我似乎无法弄清楚这一点。谢谢!
解决方案
推荐阅读
- django - 封装 PostgreSQL docker 镜像的 Kubernetes Pod 对象无限循环崩溃
- reactjs - Reactjs Token 过期时间
- python - 如何从 python 连接到 docker selenium/hub
- java - Spring data Neo4j,关系实体映射问题
- laravel - Laravel 5.5 为每个页面自动加载一个函数,而不为每个控制器调用该函数
- r - /usr/bin/ld: 找不到 -lgfortran
- mysql - 我的sql中T的作用是什么
- java - OCR 无法从该图像中正确读取字符
- sql - 保存从数据库中检索数据的顺序
- c# - C# - 从 JSON 反序列化,结果总是一个空对象