如何使用go-sql(postgres)模拟gorm插入

问题描述 投票:-1回答:1

我在Postgresql驱动程序中使用Gorm。我尝试使用go-sqlmock

模拟数据库插入
type Test struct {
    FirstName string `json:"first_name"`
}

func (db *DB) CreateTest() (*Test, error) {
    test := Test{"c"}
    if result := db.Create(&test); result.Error != nil {
        return nil, result.Error
    }

    return &test, nil
}


func TestCreateUser(t *testing.T) {
    _, mock, _ := sqlmock.NewWithDSN("sqlmock_db_0")

    mockedGorm, _ := gorm.Open("sqlmock", "sqlmock_db_0")
    defer mockedGorm.Close()
    myDB := &DB{mockedGorm}

    mock.ExpectExec("INSERT INTO test").WithArgs("c").WillReturnResult(sqlmock.NewResult(1, 1))
    myDB.Exec("INSERT INTO test(first_name) VALUES (?)", "c")


    if _, err := myDB.CreateTest(); err != nil {
        t.Errorf("error was not expected: %s", err)
    }

    if err := mock.ExpectationsWereMet(); err != nil {
        t.Errorf("there were unfulfilled expectations: %s", err)
    }
}

不幸的是,这给了我一个错误:

error was not expected: all expectations were already fulfilled, call to database transaction Begin was not expected

如何正确使用gorm,postgresql和sql-mock测试插入?

go testing gorm go-sqlmock
1个回答
0
投票
我的代码有几个问题:

1]正如@flimzy正确指出的,必须有一个ExpectBegin()(和ExpectCommit())语句。如果打开GORM调试器以显示GORM到底在做什么,这将变得更加明显。

2)ExpectExec("INSERT INTO test").WithArgs("c")显然不匹配myDB.Exec("INSERT INTO test(first_name) VALUES (?)", "c")

3)必须转义该语句,因为go-sqlmock采用了正则表达式,在这里Go的https://godoc.org/regexp#QuoteMeta派上了用场。

工作代码:

mock.ExpectBegin() mock.ExpectExec(regexp.QuoteMeta("INSERT INTO \"tests\" (\"first_name\") VALUES (?)")).WithArgs("c").WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectCommit()

© www.soinside.com 2019 - 2024. All rights reserved.