这是我参与「第五届青训营 」伴学笔记创作活动的第 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,从验证的角度来说是一样的。