dougu4704 2017-12-21 09:52
浏览 232
已采纳

如何使用带有可变数量参数的go-sqlmock WithArgs()?

I use go-sqlmock (https://godoc.org/github.com/DATA-DOG/go-sqlmock) to test a function that receives a variable number of arguments (I simplified the function for the sake of simplicity and stripped out most of the code):

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

The tests look like that:

// 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)
}

Then I get this output:

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: ...

If I change the tests like this:

mock.ExpectQuery(`^select .*`).WithArgs(actions[0], actions[1]).WillReturnRows(rows)

Then I get this output:

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:

The only I can make it pass is by calling :

db.Query(query, actions[0], actions[1])

which is what I obviously don't want to do as I don't know the number of actions...

Does anyone have an idea on how I could fix or debug this ?

  • 写回答

2条回答 默认 最新

  • dozpox8752 2017-12-21 14:34
    关注

    I found a way to fix my problem : If I convert the slice of strings to a slice of interfaces for db.Query, it works just fine:

    boundValues := make([]interface{}, len(actions))
    
    for i, val := range actions {
        boundValues[i] = val
    }
    
    rows, err := db.Query(query, boundValues...)
    

    Then for the tests:

    mock.ExpectQuery(`^select .*`).WithArgs(actions[0], actions[1]).WillReturnRows(rows)
    

    NOTE: passing just db.Query(query, actions...) does not work; this results in cannot use actions (type []string) as type []interface {} in argument to db.Query

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100
  • ¥15 关于#hadoop#的问题
  • ¥15 (标签-Python|关键词-socket)
  • ¥15 keil里为什么main.c定义的函数在it.c调用不了
  • ¥50 切换TabTip键盘的输入法
  • ¥15 可否在不同线程中调用封装数据库操作的类
  • ¥15 微带串馈天线阵列每个阵元宽度计算
  • ¥15 keil的map文件中Image component sizes各项意思
  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 划分vlan后,链路不通了?