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

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

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.

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:

确定