英文:
Testable database/sql sql.Rows in go
问题
有没有一种好的实践方法来测试/模拟执行将 sql.Rows 扫描到结构体中的函数?
func parseUsers(r *sql.Rows) (users []User, err error) {
for r.Next() {
var u User
if err = r.Scan(&u.Username,
&u.DisplayName,
&u.EmailAddress,
&u.IsEnabled,
&u.PhoneNumber); err != nil {
return []User{}, err
}
users = append(users, u)
}
err = r.Err()
return
}
但是尝试像这样做:
func TestParseUsers(t *testing.T) {
// 创建模拟的 sql.Rows
u, err := parseUsers(fakeRows)
// 进行测试...
}
我已经看过 sqlx,但是希望保持 database/sql 的结构。我也查看了 go-sqlmock,但是我正在寻找一种不需要大量构建的方法。
有没有一种适合这种类型测试的好策略?
英文:
Is there a good practice for testing/mocking functions that perform the scanning of sql.Rows into structs.
func parseUsers(r *sql.Rows) (users []User, err error) {
for r.Next() {
var u User
if err = r.Scan(&u.Username,
&u.DisplayName,
&u.EmailAddress,
&u.IsEnabled,
&u.PhoneNumber); err != nil {
return []User{}, err
}
users = append(users, u)
}
err = r.Err()
return
}
But trying to do something like:
func TestParseUsers(t *testing.T) {
//make mock sql.Rows
u, err := parseUsers(fakeRows)
//Do tests...
}
I have looked at sqlx, but would like to keep the database/sql structure. And I checked go-sqlmock, but I am looking for something without a large build up.
Is there a good strategy for this sort of test?
答案1
得分: 0
使用接口作为输入的方法是Go语言的一种常见方式。
在你的情况下,可以这样写:
type Scanner interface {
Next()
Scan(User)
}
func parseUsers(s Scanner) (users []User, err error) {
// ...
}
现在测试非常简单,因为你可以创建一个模拟的扫描器,它实现了接口并记住了方法被调用时的参数。
英文:
The go way would be to use an interface as input.
In your case it could look like this:
type Scanner interface {
Next()
Scan(User)
}
The function should look like this:
func parseUsers(s Scanner) (users []User, err error) {
// ...
}
Now testing is very easy, because you can create a mock scanner, which implements the interface and remembers, with which parameters the methods has been called.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论