L'éditeur PHP Xinyi est là pour vous présenter un problème concernant Gorm : lorsque nous utilisons Gorm pour effectuer des requêtes de base de données, des ordres de colonnes différents peuvent provoquer un échec des tests. En effet, lorsque Gorm effectue une requête, il génère des instructions SQL basées sur l'ordre des champs dans la structure. Si nous spécifions un ordre de colonnes spécifique dans la requête, mais que l'ordre des champs dans la structure ne correspond pas, le test échouera. Par conséquent, lorsque nous utilisons Gorm pour des requêtes de base de données, nous devons faire attention à ce que l'ordre des champs dans la structure soit cohérent avec l'ordre des colonnes dans la requête pour éviter ce problème.
Dans mon code j'ai le modèle suivant :
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"` }
J'utilise la méthode gorm.DB
结构的 CreateInBatches
.
J'utilise go-sqlmock pour les tests unitaires. Dans ce modèle, seules les opérations d'insertion sont effectuées.
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)))) }
Mes cas de test échouent parfois en raison de l'ordre différent de create_date
和 update_date
.
L'un des échecs est
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 \(\?,\?,\?,\?,\?\)"
Pour mon cas d'utilisation, l'ordre des colonnes dans l'insert n'a pas d'importance. Comment puis-je gérer cela dans les tests unitaires pour gérer tous les scénarios ?
Après avoir lu la documentation sqlmock ici J'ai obtenu la solution de contournement suivante :
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)))) }
J'ai supprimé les colonnes et les valeurs. Dans mon cas, je n'ai pas besoin de me soucier du champ create_date
和 update_date
, donc ça fonctionne très bien.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!