Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Argument matching for queries using unpacked slices #331

Open
gkoscky opened this issue Dec 20, 2023 · 0 comments
Open

Argument matching for queries using unpacked slices #331

gkoscky opened this issue Dec 20, 2023 · 0 comments

Comments

@gkoscky
Copy link

gkoscky commented Dec 20, 2023

I have a sqlx.Query being called on a named query with multiple parameters. You can see a working example, but here's the abridged version:

type myStruct struct {
  ColumnA string   `db:"columnA"`
  ColumnB string   `db:"columnB"`
  ColumnC []string `db:"columnC"`
}

func runQuery(db *sqlx.DB, arguments myStruct) ([]myStruct, error) {
  namedQuery := "SELECT * FROM my_table WHERE columnA = :columnA AND columnB = :columnB AND columnC IN (:columnC)"
  
  query, args, _ := sqlx.Named(namedQuery, arguments)
  query, args, _ = sqlx.In(query, args...)
  query = db.Rebind(query)
  
  rows, err := db.Queryx(query, args...)
  if err != nil {
    return nil, fmt.Errorf("error querying: %s", err)
  }
  //…
}

And then a test case like so

  mockDb, mock, err := sqlmock.New()
  sqlxDB := sqlx.NewDb(mockDb, "sqlmock")
  
  toQuery := myStruct{
    ColumnA: "testA",
    ColumnB: "testB",
    ColumnC: []string{"testC", "testD"},
  }
  
  queryArgs := []string{"testA", "testB", "testC", "testD"}
  
  returnRows := mock.NewRows([]string{"columnA", "columnB"}).AddRow("returnA", "returnB")
  mock.ExpectQuery("SELECT \\* FROM my_table ").WithArgs(queryArgs).WillReturnRows(returnRows)
  
  _, err = runQuery(sqlxDB, toQuery)
  if err != nil {
    log.Println(err)
    return
  }

Which results in this error message:

Query 'SELECT * FROM my_table WHERE columnA = ? AND columnB = ? AND columnC IN (?, ?)',
  arguments do not match: expected 1, but got 4 arguments

The error makes sense, because I am passing queryArgs ([]string) to WithArgs, while the actual Queryx(query, args...) method gets an unpacked []interface{} as its arguments. But doing a similar AddRow(queryArgs...) results in:

cannot use queryArgs (variable of type []string) as []driver.Value value in argument to mock.ExpectQuery

Which leads me to my question: How can I pass an array to WithArgs that would match the unpacked arguments passed to Queryx?

I know I could hard code it, but in the non-simplified version of this code, the number of arguments is variable for each test case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant