可测试的数据库/sql中的sql.Rows在Go中的使用

huangapple go评论116阅读模式
英文:

Testable database/sql sql.Rows in go

问题

有没有一种好的实践方法来测试/模拟执行将 sql.Rows 扫描到结构体中的函数?

  1. func parseUsers(r *sql.Rows) (users []User, err error) {
  2. for r.Next() {
  3. var u User
  4. if err = r.Scan(&u.Username,
  5. &u.DisplayName,
  6. &u.EmailAddress,
  7. &u.IsEnabled,
  8. &u.PhoneNumber); err != nil {
  9. return []User{}, err
  10. }
  11. users = append(users, u)
  12. }
  13. err = r.Err()
  14. return
  15. }

但是尝试像这样做:

  1. func TestParseUsers(t *testing.T) {
  2. // 创建模拟的 sql.Rows
  3. u, err := parseUsers(fakeRows)
  4. // 进行测试...
  5. }

我已经看过 sqlx,但是希望保持 database/sql 的结构。我也查看了 go-sqlmock,但是我正在寻找一种不需要大量构建的方法。

有没有一种适合这种类型测试的好策略?

英文:

Is there a good practice for testing/mocking functions that perform the scanning of sql.Rows into structs.

  1. func parseUsers(r *sql.Rows) (users []User, err error) {
  2. for r.Next() {
  3. var u User
  4. if err = r.Scan(&u.Username,
  5. &u.DisplayName,
  6. &u.EmailAddress,
  7. &u.IsEnabled,
  8. &u.PhoneNumber); err != nil {
  9. return []User{}, err
  10. }
  11. users = append(users, u)
  12. }
  13. err = r.Err()
  14. return
  15. }

But trying to do something like:

  1. func TestParseUsers(t *testing.T) {
  2. //make mock sql.Rows
  3. u, err := parseUsers(fakeRows)
  4. //Do tests...
  5. }

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语言的一种常见方式。

在你的情况下,可以这样写:

  1. type Scanner interface {
  2. Next()
  3. Scan(User)
  4. }
  5. func parseUsers(s Scanner) (users []User, err error) {
  6. // ...
  7. }

现在测试非常简单,因为你可以创建一个模拟的扫描器,它实现了接口并记住了方法被调用时的参数。

英文:

The go way would be to use an interface as input.

In your case it could look like this:

  1. type Scanner interface {
  2. Next()
  3. Scan(User)
  4. }

The function should look like this:

  1. func parseUsers(s Scanner) (users []User, err error) {
  2. // ...
  3. }

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.

huangapple
  • 本文由 发表于 2017年2月15日 23:37:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/42253698.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定