gorm 测试 简记

112 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 6 天

GORM是一个最火的Go语言ORM库(从GitHub的星星来说),它提供了一种方便的方式来操作数据库。而不用没完没了的和SQL打交道,更不用说它的子项目gen了。 不过再好用的功能也需要一定的测试才能保证正常完成我们的工作,在编写测试时,我们可能不想使用实际的数据库,而是希望使用虚拟数据库进行测试。SQLMock就是一个这样的工具,SQLMock是最火的的Go语言SQL模拟库(也是从星星来说),它可以模拟SQL数据库的行为,从而使我们能够轻松地编写和运行测试。在本文中,我们将讨论如何使用SQLMock测试GORM。 简单的使用示例如下

const query = `const findOneUser = "SELECT * FROM `users` WHERE `users`.`id` = ? ORDER BY `users`.`id` LIMIT 1"`
mock.ExpectQuery(query).
    WithArgs(1).
    WillReturnRows(
        sqlmock.NewRows([]string{"id", "username", "password”}).
            AddRow(1, "A", "B"))

上面这部分是mock的最主要部分,我们可以看到,我们使用了ExpectQuery来指定我们期望的查询语句,然后使用WithArgs来指定我们期望的参数,最后使用WillReturnRows来指定我们期望的返回结果。 而且并不需要我们去指定返回结果的类型,它会自动根据我们的返回结果来推断对比,就像平常我们mock接口的输出以及输出一样。 当然由于是最主要的部分,所以缺失一些东西,比如代码里的mock是什么?mock是怎么初始化的? 因此这里我们再来看一下初始化的部分

db, mock, err := sqlmock.New()
if err != nil {
    // t.Fatalf("error creating mock: %v", err)
}

那么我们就可以看到,我们使用了sqlmock.New()来初始化我们的mock,这个函数会返回三个值,第一个是我们的mock的数据库连接,第二个是我们的mock(用于设置预期行为),第三个是错误信息。 基于数据库连接db去创建gorm的db就不多说了,直接使用它的MySQL驱动自带的方法就可以了 然后就是具体的测试了。

func TestFindOne(t *testing.T) {
    // 省略初始化部分
    user := User{}
    gormDB.Where("id = ?", 1).First(&user)
    if user.ID != 1 {
        t.Fatalf("error finding user: %v", err)
    }
}

实际上,返回的数据还有username和password,但是这里我们只是测试了ID,从验证的角度来说是一样的。