In my code, I have following model:
type ID uint64
type BaseModel struct {
ID ID `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
UpdateDate time.Time `gorm:"column:update_date;default:CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP" json:"update_date"`
CreateDate time.Time `gorm:"column:create_date;default:CURRENT_TIMESTAMP" json:"create_date"`
}
type Rollback struct {
BaseModel
PID ID `gorm:"index"`
Table string `gorm:"column:tbl_name"`
RollbackRow string `gorm:"type:longtext"`
}
I am using CreateInBatches
method of gorm.DB
struct.
I have unit tests using go-sqlmock. In this model, only insert operations are performed.
func expectRollbackInsert(mock sqlmock.Sqlmock, tablename []string) {
args := make([]driver.Value, 0)
for _, val := range tablename {
args = append(args, 1, val, sqlmock.AnyArg(), sqlmock.AnyArg(), sqlmock.AnyArg())
}
mock.ExpectExec(regexp.QuoteMeta("INSERT INTO `rollback` (`payment_id`,`tbl_name`,`rollback_row`,`update_date`,`create_date`) VALUES (?,?,?,?,?)")).
WithArgs(args...).
WillReturnResult(sqlmock.NewResult(int64(len(tablename)), int64(len(tablename))))
}
My test cases are failing sometimes due to different order of create_date
and update_date
.
One such failure is
ExecQuery: could not match actual sql: "INSERT INTO `rollback` (`pid`,`tbl_name`,`rollback_row`,`create_date`,`update_date`) VALUES (?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?)" with expected regexp "INSERT INTO `rollback` \(`pid`,`tbl_name`,`rollback_row`,`update_date`,`create_date`\) VALUES \(\?,\?,\?,\?,\?\)"
For my use-case, order of column does not matter in insert. How can I handle it in unit-tests to handle all the scenario?
After reading sqlmock documentation here, I got the following workaround:
func expectRollbackInsert(mock sqlmock.Sqlmock, tablename []string) {
args := make([]driver.Value, 0)
for _, val := range tablename {
args = append(args, 1, val, sqlmock.AnyArg(), sqlmock.AnyArg(), sqlmock.AnyArg())
}
mock.ExpectExec(regexp.QuoteMeta("INSERT INTO `rollback`")).
WithArgs(args...).
WillReturnResult(sqlmock.NewResult(int64(len(tablename)), int64(len(tablename))))
}
I removed columns and values. In my case, I do not need to care about create_date
and update_date
field, hence it worked fine.