微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Go 单元测试 - 在使用 go-sqlmock 模拟 gorm 时无法将实际 sql 与预期的正则表达式匹配?

如何解决Go 单元测试 - 在使用 go-sqlmock 模拟 gorm 时无法将实际 sql 与预期的正则表达式匹配?

在进行单元测试时,我使用 sqlmock 模拟 gorm。但是当运行所有初始设置时都很好,但是当实际查询和测试查询匹配时会发生错误。我在下面给出了所有代码

user.go

func (r *users) GetUserByID(userID uint) (*domain.User,*errors.RestErr) {
    var resp domain.User

    res := r.DB.Model(&domain.User{}).Where("id = ?",userID).First(&resp)

    if res.RowsAffected == 0 {
        logger.Error("error occurred when getting user by user id",res.Error)
        return nil,errors.NewNotFoundError(errors.ErrRecordNotFound)
    }

    return &resp,nil
}

模拟

user_test.go

type Suite struct {
    suite.Suite
    DB         *gorm.DB
    mock       sqlmock.sqlmock
    db         *sql.DB
    err        error
    repository repository.IUsers
}

func (s *Suite) SetupSuite() {
    s.db,s.mock,s.err = sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))

    require.NoError(s.T(),s.err)

    dialector := MysqL.New(MysqL.Config{
        DSN:                       "sqlmock_db_0",DriverName:                "MysqL",Conn:                      s.db,SkipInitializeWithVersion: true,})

    s.DB,s.err = gorm.Open(dialector,&gorm.Config{})

    require.NoError(s.T(),s.err)
    s.repository = impl.NewMysqLUsersRepository(s.DB)
}

func (s *Suite) AfterTest(_,_ string) {
    require.NoError(s.T(),s.mock.ExpectationsWereMet())
}

func Testinit(t *testing.T) {
    suite.Run(t,new(Suite))
}

// .................Start Testing....................

func (s *Suite) Test_repository_Get() {
    var (
        id        = uint(1)
        user_name = "user-name"
        fast_name = "fast-name"
    )

    s.mock.ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "users" WHERE (id = $1) ORDER BY "users"."id" LIMIT 1`)).
        WithArgs(uint(id)).
        WillReturnRows(sqlmock.NewRows([]string{"id","user_name","fast_name"}).
            AddRow(uint(id),user_name,fast_name))

    res,_ := s.repository.GetUserByID(uint(id))
    require.Nil(s.T(),deep.Equal(&domain.User{ID: uint(id),UserName: user_name,LastName: fast_name},res))
}

当我执行 res,_ := s.repository.GetUserByID(uint(id)) 这一行时,它转到 user.go 文件。这里在 sql 查询行中出现错误如下所示。

actual sql: "SELECT * FROM `users` WHERE id = ? ORDER BY `users`.`id` LIMIT 1" 
does not equal to expected "SELECT \* FROM "users" WHERE \(id = \$1\) ORDER BY "users"\."id" LIMIT 1"


=> expecting Query,QueryContext or QueryRow which:
     - matches sql: 'SELECT \* FROM "users" WHERE \(id = \$1\) ORDER BY "users"\."id" LIMIT 1'
     - is with arguments:
                0 - 1
     - should return rows:
                row 0 - [1 user-name fast-name]

这里有什么问题?

解决方法

这里的主要问题是sql查询。对于 Get-Item,这里不需要完整查询。 Gorm 自动生成这个。只需要通过

"SELECT(.*)"

我是从 Medium 上的一篇博文中发现的。 Here you can find details

波纹管代码工作正常

func (s *Suite) Test_repository_GetUserByID() {
var (
    id         = uint(1)
    user_name  = "user-name"
    first_name = "first-name"
)
s.mock.ExpectQuery("SELECT(.*)").
    WithArgs(id).
    WillReturnRows(sqlmock.NewRows([]string{"id","user_name","first_name"}).
        AddRow(uint(id),user_name,first_name))

 res,_ := s.repository.GetUserByID(uint(id))
 require.Nil(s.T(),deep.Equal(&domain.User{ID: uint(id),UserName: user_name,FirstName: first_name},res))
 }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。