首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用具有可变参数数的go-sqlmock ()?

如何使用具有可变参数数的go-sqlmock ()?
EN

Stack Overflow用户
提问于 2017-12-21 09:52:10
回答 3查看 10.5K关注 0票数 5

我使用go-sqlmock (https://godoc.org/github.com/DATA-DOG/go-sqlmock)测试接收可变数量参数的函数(为了简单起见,我简化了该函数,并去掉了大部分代码):

代码语言:javascript
复制
func getHits(db *sql.DB, actions ...string) (hits []Hit, err error) {
   // ...
   query := `select * from table where action in (?,?)`
   rows, err := db.Query(query, actions)
   // ...
}

测试看起来是这样的:

代码语言:javascript
复制
// rows := ...
actions := []string{"click", "event"}
mock.ExpectQuery(`^select .*`).WithArgs(actions).WillReturnRows(rows)
hits, err := getHits(db, actions...)
if mockErr := mock.ExpectationsWereMet(); mockErr != nil {
    log.Fatalf("there were unfulfilled expections: %s", mockErr)
}

然后我得到这个输出:

代码语言:javascript
复制
2017/12/21 10:38:23 there were unfulfilled expections: there is a remaining expectation which was not matched: ExpectedQuery => expecting Query or QueryRow which:
- matches sql: '^select .*'
- is with arguments:
  0 - [click event]
- should return rows: ...

如果我像这样改变测试:

代码语言:javascript
复制
mock.ExpectQuery(`^select .*`).WithArgs(actions[0], actions[1]).WillReturnRows(rows)

然后我得到这个输出:

代码语言:javascript
复制
2017/12/21 10:44:41 there were unfulfilled expections: there is a remaining expectation which was not matched: ExpectedQuery => expecting Query or QueryRow which:
- matches sql: '^select .*'
- is with arguments:
  0 - click
  1 - event
- should return rows:

我唯一能通过的就是打电话:

代码语言:javascript
复制
db.Query(query, actions[0], actions[1])

这显然是我不想做的,因为我不知道有多少行动.

有人知道我如何修复或调试这个问题吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-12-21 14:34:26

我找到了一种解决问题的方法:如果我将字符串的片段转换为db.Query的接口片段,那么它的工作效果很好:

代码语言:javascript
复制
boundValues := make([]interface{}, len(actions))

for i, val := range actions {
    boundValues[i] = val
}

rows, err := db.Query(query, boundValues...)

然后在测试中:

代码语言:javascript
复制
mock.ExpectQuery(`^select .*`).WithArgs(actions[0], actions[1]).WillReturnRows(rows)

注意:只传递db.Query(query, actions...)不起作用;这将导致cannot use actions (type []string) as type []interface {} in argument to db.Query

票数 2
EN

Stack Overflow用户

发布于 2018-03-16 08:28:34

使用[]interface{}接受的答案可以用于字符串,但它可能会引发其他类型的错误。

短答案

代码语言:javascript
复制
actions := []driver.Value{"click", "event"}
mock.ExpectQuery(`^select .*`).WithArgs(actions...).WillReturnRows(rows)

长答案

参数要求driver.Value 参考文献和driver.Value可以是这些类型中的一个

  • int64
  • float64
  • 布尔值
  • []字节
  • 字符串
  • time.Time

所以,正确的答案是

代码语言:javascript
复制
actions := []driver.Value{"click", "event"}
mock.ExpectQuery(`^select .*`).WithArgs(actions...).WillReturnRows(rows)
票数 5
EN

Stack Overflow用户

发布于 2020-06-14 09:59:14

一个更清洁的解决方案是使用这个。

代码语言:javascript
复制
/* Prepare database mock */
type AnyNumber struct{}

// Match satisfies sqlmock.Argument interface
func (a AnyNumber) Match(v driver.Value) bool {
    _, ok := v.(float64)
    return ok
}

然后使用AnyNumber{}作为WithArgs中的参数

以下是docs 单击此处中的引用

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47922204

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档