go-sqlmock
go-sqlmock copied to clipboard
Why this sql not match when using postgres?
call to Query 'INSERT INTO "topic" ("name","tags","create_by","score","agree","disagree","create_time","update_time") VALUES ($1,$2,$3,$4,$5,$6,$7,$8) RETURNING "id"' with args [{Name: Ordinal:1 Value:t1} {Name: Ordinal:2 Value:} {Name: Ordinal:3 Value:} {Name: Ordinal:4 Value:0} {Name: Ordinal:5 Value:0} {Name: Ordinal:6 Value:0} {Name: Ordinal:7 Value:2020-10-14 17:47:49} {Name: Ordinal:8 Value:2020-10-14 17:47:49}], was not expected, next expectation is: ExpectedExec => expecting Exec or ExecContext which:
- matches sql: 'INSERT INTO "topic" ("name","tags","create_by","score","agree","disagree","create_time","update_time") VALUES ($1,$2,$3,$4,$5,$6,$7,$8) RETURNING "id"'
- is with arguments:
0 - {}
1 - {}
2 - {}
3 - {}
4 - {}
5 - {}
6 - {}
7 - {}
- should return Result having:
LastInsertId: 15
RowsAffected: 1
mock.ExpectExec(`INSERT INTO "topic" ("name","tags","create_by","score","agree","disagree","create_time","update_time") VALUES ($1,$2,$3,$4,$5,$6,$7,$8) RETURNING "id"`).
WithArgs(sqlmock.AnyArg(),sqlmock.AnyArg(),sqlmock.AnyArg(),sqlmock.AnyArg(),sqlmock.AnyArg(),sqlmock.AnyArg(),sqlmock.AnyArg(),sqlmock.AnyArg()).
WillReturnResult(sqlmock.NewResult(15, 1))
mock.ExpectExec(`INSERT INTO "topic"`).
WillReturnResult(sqlmock.NewResult(15, 1))
this config don't match too
I don't know why this sql can't match!
call to Query 'INSERT INTO "topic" ("name","tags","create_by","score","agree","disagree") VALUES ($1,$2,$3,$4,$5,$6) RETURNING "id"' with args [{Name: Ordinal:1 Value:t1} {Name: Ordinal:2 Value:} {Name: Ordinal:3 Value:} {Name: Ordinal:4 Value:0} {Name: Ordinal:5 Value:0} {Name: Ordinal:6 Value:0}], was not expected, next expectation is: ExpectedExec => expecting Exec or ExecContext which:
- matches sql: 'INSERT INTO "topic"'
- is with arguments:
0 - t1
1 -
2 -
3 - 0
4 - 0
- should return Result having:
LastInsertId: 15
RowsAffected: 1
@file sqlmock_go18.go
return from here,so not match happened ,Incomprehensible
I understand why not match!
because I using xorm,when save will query context first (queryDC) .
the next
type not match then sqlmock return nil.
to fix this,sqlmock can ignore queryContext maybe
this casuse by xorm
using QueryContext for insert when datebase is postgres,mssql,oracle.
so when you using mysql this will not happend
注意:使用mysql以上是没问题的 如果你使用的是Postgres或oracle有问题,因为如果是以上数据库xorm是通过QueryContext执行的插入,加上mocksql的Expected类型判断和执行sql什么API绑定的,不是根据SQL解析的。
Sqlmock is based on a standard sql driver interface. It will not try to adapt to different frameworks, which use it in non standard expected ways. So you can just fork it and customize
Maybe if you are expected exec, instead expect query, this probably will work
I have the same problem with xorm
, which is blocked me long time.
As @seven4x said, xorm
implement postgres
's insert and returning id by QueryContext
, so sqlmock
has to used ExpectQuery
as expected method.
After some test, I found a solution with this situation: using ExpectQuery
instead of ExpectExec
.
s.SqlMock.ExpectQuery(regexp.QuoteMeta(`INSERT INTO "table" ("id","unique_id","status","create_time","update_time","group_id","user_id") VALUES ($1,$2,$3,$4,$5) RETURNING "id"`)).
WithArgs(tt.args.po.Id, tt.args.po.UniqueId, tt.args.po.Status, sqlmock.AnyArg(), sqlmock.AnyArg()).
WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(1))
//s.SqlMock.ExpectExec(regexp.QuoteMeta(`INSERT INTO "table" ("id","unique_id","status","create_time","update_time") VALUES ($1,$2,$3,$4,$5) RETURNING "id"`)).
// WithArgs(tt.args.po.Id, tt.args.po.UniqueId, tt.args.po.Status, sqlmock.AnyArg(), sqlmock.AnyArg()).
// WillReturnResult(
// sqlmock.NewResult(1, 1),
// )
It will work as same as ExpectExec.
如果有人遇到相同问题, 可以考虑用 ExpectQuery
代替 ExpectExec
执行, 它能得到类似的作用, 并且验证通过。