Closed navono closed 5 years ago
Yes,I have met this too.
@l3pp4rd Could you have a look at this?
gorm@v1.9.2
// Begin start a transaction
func (scope *Scope) Begin() *Scope {
if db, ok := scope.SQLDB().(sqlDb); ok {
if tx, err := db.Begin(); err == nil {
scope.db.db = interface{}(tx).(SQLCommon)
scope.InstanceSet("gorm:started_transaction", true)
}
}
return scope
}
and gorm@v1.9.11
// Begin start a transaction
func (scope *Scope) Begin() *Scope {
if db, ok := scope.SQLDB().(sqlDb); ok {
if tx, err := db.Begin(); scope.Err(err) == nil {
scope.db.db = interface{}(tx).(SQLCommon)
scope.InstanceSet("gorm:started_transaction", true)
}
}
return scope
}
at 1.9.2, gorm not check db.Begin()
error and 1.9.11 do, so the error saved to db.Error
cause tests failed.
The main reasone is in sqlmock.begin()
, the c.ordered
always true and return error from it.
func (c *sqlmock) begin() (*ExpectedBegin, error) {
...
if c.ordered {
return nil, fmt.Errorf("call to database transaction Begin, was not expected, next expectation is: %s", next)
}
}
...
}
After dig a little about sqlmock, I think sqlmock is fine. The right way is use MatchExpectationsInOrder
to disable order
and add ExpectBegin
as this:
s.mock.MatchExpectationsInOrder(false)
s.mock.ExpectBegin()
s.mock.ExpectQuery(regexp.QuoteMeta(
`INSERT INTO "person" ("id","name")
VALUES ($1,$2) RETURNING "person"."id"`)).
WithArgs(id, name).
WillReturnRows(
sqlmock.NewRows([]string{"id"}).AddRow(id.String()))
s.mock.ExpectCommit()
Another problem is that it doesn't support sqlite3
Mysql is not supported yet. this is the output when I replace "postgres" to "mysql" :
call to ExecQuery 'INSERT INTO
users(
id,
name) VALUES (?,?)' with args [{Name: Ordinal:1 Value:1e2f940d-06e0-4c64-9fc3-5cbe81179280} {Name: Ordinal:2 Value:test-name}] was not expected
From the db log I find that:
Mysql execute sql is INSERT INTO `users` (`id`,`name`) VALUES ('1e2f940d-06e0-4c64-9fc3-5cbe81179280','test-name')
Postgresql execute sql is INSERT INTO "users" ("id","name") VALUES ('1e2f940d-06e0-4c64-9fc3-5cbe81179280','test-name') RETURNING "users"."id"
Below two "sqls" is different, I try to update regexp.QuoteMeta
with escaping "`" but failed.
Same as sqlite3
. Another way is like this, but I haven't checked it yet.
Hi, I followed the @navono solution but I'm still having problem while trying to execute the INSERT, (with postgres driver) here is my code:
func TestRegister(t *testing.T) {
qStr := `INSERT INTO "customer" ("customer_key","first_name","middle_name","last_surname")
VALUES ($1,$2,$3,$4) RETURNING "customer"."customer_key"`
t.Run("Must return the newly created customer key, if given customer input is valid", func(t *testing.T) {
r := mocks.CustomerModel
mock.MatchExpectationsInOrder(false)
mock.ExpectBegin()
mock.ExpectQuery(regexp.QuoteMeta(qStr)).
WithArgs(r.CustomerKey, r.FirstName, r.MiddleName, r.LastSurname).
WillReturnRows(sqlmock.NewRows([]string{"customer_key"}).AddRow(r.CustomerKey))
mock.ExpectCommit()
customerKey, err := repo.Register(r)
assert.Nil(t, err)
assert.NotNil(t, customerKey)
})
}
and I get the following error:
Running tool: /usr/local/go/bin/go test -timeout 30s /internal/customer -run ^(TestRegister)$
call to Query 'INSERT INTO "customer" ("customer_key","first_name","middle_name","last_surname",ationality_id","category_id") VALUES ($1,$2,$3,$4) RETURNING "customer"."customer_key"' with args [{Name: Ordinal:1 Value:RLKuxK-wnj8SUn50iFMjsrCtikTLTEmUFP7fOSE2veI=}
{Name: Ordinal:2 Value:Martín} {Name: Ordinal:3 Value:Constan}
{Name: Ordinal:4 Value:Smith}]
was not expected <----------------------ERROR-------------------------
INSERT INTO "customer" ("customer_key","first_name","middle_name","last_surname") VALUES ('RLKuxK-wnj8SUn50iFMjsrCtikTLTEmUFP7fOSE2veI=','Martín','','Constan','Smith'') RETURNING "customer"."customer_key"
[0 rows affected or returned ]
[35m(data-repository/internal/customer/repository.go:57)[0m
[33m[2020-01-22 19:39:18][0m [31;1m call to Query 'INSERT INTO "customer" ("customer_key","first_name","middle_name","last_surname",ationality_id","category_id") VALUES ($1,$2,$3,$4) RETURNING "customer"."customer_key"' with args [{Name: Ordinal:1 Value:RLKuxK-wnj8SUn50iFMjsrCtikTLTEmUFP7fOSE2veI=} {Name: Ordinal:2 Value:Martín} {Name: Ordinal:3 Value:Constan} {Name: Ordinal:4 Value:Smith}]
was not expected <----------------------ERROR AGAIN-------------------------
--- FAIL: TestRegister (0.00s)
--- FAIL: TestRegister/Must_return_the_newly_created_customer_key,_if_given_customer_input_is_valid (0.00s)
data-repository/internal/customer/repository_test.go:89:
Error Trace: repository_test.go:89
Error: Expected nil, but got: &status.statusError{Code:13, Message:"An error occurred.", Details:[]*any.Any{(*any.Any)(0xc000215f90)}, XXX_NoUnkeyedLiteral:struct {}{}, XXX_unrecognized:[]uint8(nil), XXX_sizecache:0}
Test: TestRegister/Must_return_the_newly_created_customer_key,_if_given_customer_input_is_valid
FAIL
FAIL /internal/customer 0.008s
FAIL
Error: Tests failed.
I'm using the following versions:
github.com/DATA-DOG/go-sqlmock v1.4.0 github.com/jinzhu/gorm v1.9.11
Hi @navono, would you check this issue please #215
Hi, @navono , I am having the same issue, and tried to the solution you mentioned, while it doesn't work for me, but the message changed to the below,
call to database transaction Begin was not expected
I am guessing it's related to gorm?, so opened a ticket there,https://github.com/jinzhu/gorm/issues/2965
Can you pls give any advice to this issue?
thanks
Use gorm-ut source with upgrade deps version, go.mod:
and run test, command line shows:
If not upgrade deps, keep it with origin repo, it works.