xorm和sqlmock结合的踩坑指南

首先明确一点:
xorm中查询多条数据可以使用Find方法,Find方法的第一个参数为slice的指针Map指针
举个例子:

// 错误示例
var person []Person
db.where("age = ?", 18).Find(person) // 错误,得传person的地址,尽管person是指针类型// 正确示例
var person []Person
db.where("age = ?", 18).Find(&person)

如果以上这点没注意到,那么应结合Find函数返回的报错信息进行检测,报错信息很重要,能帮助我们排查错误。比如engine.ShowSQL(true)语句不生效,SQL语句打印不出来,很可能是执行SQL前那个函数报错了。
接下进入正题,先看看下面代码:

type Person struct {
    Age int `xorm:"not null"`
    Sex string `xorm:"not null"`
}func GetPerson(db *xorm.Engine, age int) []*Person {
    var p []*Person
    err := db.Where("age = ?", age).Limit(1).Find(&p)
    if err != nil {
        fmt.Println(err.Error()) // 很重要,这步错误处理不要省略,帮助定位问题
    }
    return p
}
func TestGetPerson(t *testing.T) {
    db, mock, _ := sqlmock.New()
    defer db.Close()
    mock.ExpectBegin()
    row := sqlmock.NewRows([]string{"age", "sex"}).AddRow(18, "男")
    mock.ExpectQuery("^SELECT \\* FROM `person` where age = \\?").WillReturnRows(row)
    engine,_ := xorm.NewEngine("mysql", "root:123@/test?charset=utf-8")
    engine.ShowSQL(true)
    engine.DB().DB = db
    p := GetPerson(engine, 18)
    fmt.Println(p)
}

上述代码中,GetPerson中报错信息显示:
call to Query ‘SELECT `age`, `sex` FROM `person` WHERE (age = ?) LIMIT 1’ with args [{Name: Ordinal:1 Value:18}], was not expected, next expectation is: ExpectedBegin => expecting database transaction Begin
这段报错表示ExpectQuery函数中传递的正则语句与实际执行的SQL语句没有匹配,根据这段报错信息或打印出来的SQL语句,应该将正则改为:
mock.ExpectQuery(“SELECT `age`, `sex` FROM `person` WHERE \\(age = \\?\\) LIMIT 1”)
或者再简单一点:
mock.ExpectQuery(“SELECT .* FROM `person`”)
只要正则匹配都行。
上述代码还有一个错误,那就是缺少engine.DB().Begin()。其实段语句可要可不要,视情况而定。当出现了mock.ExpectBegin()时,需要加上engine.DB().Begin(),否则不加。因为这两个语句是相匹配的,默认匹配,就像正则一样。
正确精简的版本:

type Person struct {
    Age int `xorm:"not null"`
    Sex string `xorm:"not null"`
}func GetPerson(db *xorm.Engine, age int) []*Person {
    var p []*Person
    err := db.Where("age = ?", age).Limit(1).Find(&p)
    if err != nil {
        fmt.Println(err.Error())
    }
    return p
}func TestGetPerson(t *testing.T) {
    db, mock, _ := sqlmock.New()
    defer db.Close()
    row := sqlmock.NewRows([]string{"age", "sex"}).AddRow(18, "男")
    mock.ExpectQuery("SELECT .* FROM `person`").WillReturnRows(row)
    engine,_ := xorm.NewEngine("mysql", "root:123@/test?charset=utf-8")
    engine.ShowSQL(true)
    engine.DB().DB = db
    p := GetPerson(engine, 11)
    if len(p) > 0 {
        fmt.Println(p[0])
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值