我一直在尝试把我的头缠在单元测试,依赖注入,tdd和所有的东西上,我一直在测试进行数据库调用的函数,例如。
假设您有一个PostgresStore结构体,它接收一个Database接口,该接口具有一个Query()方法。
type PostgresStore struct {
db Database
}
type Database interface {
Query(query string, args ...interface{}) (*sql.Rows, error)
}
PostgresStore有一个GetPatients方法,它调用数据库查询。
func (p *PostgresStore) GetPatients() ([]Patient, error) {
rows, err := p.db.Query("SELECT id, name, age, insurance FROM patients")
if err != nil {
return nil, err
}
defer rows.Close()
items := []Patient{}
for rows.Next() {
var i Patient
if err := rows.Scan(
&i.ID,
&i.Name,
&i.Surname,
&i.Age,
&i.InsuranceCompany,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
在真实的的实现中,你只需要传递一个 * sql.DB作为数据库参数,但是你们怎么用一个假的数据库结构来编写单元测试呢?
1条答案
按热度按时间nwlqm0z11#
让我试着澄清你们的一些疑问。首先,我将分享一个工作示例,以便更好地理解正在发生的事情。然后,我将提到所有相关的方面。
一个月一次
这里,唯一相关的变化是如何定义
PostgresStore
结构体。作为db
字段,您应该依赖Go语言标准库的database/sql
包提供的泛型DB
。因此,将其实现替换为一个伪实现是很容易的,我们稍后会看到。请注意,在
GetPatient
方法中,您接受了一个id
参数,但没有使用它。您的查询更适合GetAllPatients
或类似的方法。请确保相应地修复它。repo/db_test.go
这里有很多内容要介绍。首先,你可以查看代码中的注解,这些注解可以让你更好地了解每一步。在代码中,我们依赖于
github.com/DATA-DOG/go-sqlmock
包,它允许我们轻松地模拟数据库客户端。显然,这段代码的目的是给出一个关于如何实现你的需求的总体概念。它可以用一种更好的方式编写,但它可以是在这种场景中编写测试的一个很好的起点。
如果有帮助,请告诉我,谢谢!