Home > Backend Development > Golang > Gorm different column order and test failure

Gorm different column order and test failure

王林
Release: 2024-02-10 15:20:10
forward
447 people have browsed it

Gorm 不同的列顺序和测试失败

php editor Xinyi is here to introduce to you a problem about Gorm: when we use Gorm to perform database queries, different column orders may cause test failure. This is because when Gorm performs a query, it will generate SQL statements based on the order of the fields in the structure. If we specify a specific column order in the query, but the field order in the structure does not match it, the test will fail. Therefore, when using Gorm for database queries, we need to pay attention to the order of the fields in the structure being consistent with the order of the columns in the query to avoid this problem.

Question content

In my code, I have the 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"`
}
Copy after login

I am using the CreateInBatches method of the gorm.DB structure.

I use go-sqlmock for unit testing. 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))))
}
Copy after login

My test cases sometimes fail due to the different order of create_date and update_date.

One of the failures 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 \(\?,\?,\?,\?,\?\)"
Copy after login

For my use case, the order of the columns in the insert does not matter. How can I handle this in unit tests to handle all scenarios?

Solution

After reading the sqlmock documentation here, I got the following solution:

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))))
}
Copy after login

I deleted the columns and values. In my case, I don't need to care about the create_date and update_date fields, so it works just fine.

The above is the detailed content of Gorm different column order and test failure. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template