duandong9195 2019-08-30 01:07
浏览 277

如何正确设置模拟行和查询go-sqlmock

I'm setting up testing in golang.
I use go-sqlmock to test mysql connection.
But sqlmock.NewRows and mock.ExpectQuery does not work well with error.
I want to know how to resolve this error.

server side: golang
db: mysql
web framework: gin

dao.go

func GetSingleArticleDao(c *gin.Context, db *sql.DB) (util.Article, *sql.Rows) {
    id := c.Params.ByName("id")
    article := util.Article{}
    errArticle := db.QueryRow("SELECT * FROM articles WHERE id = ?", id).Scan(&article.ID, &article.UUID, &article.TITLE, &article.CONTENT)
    if errArticle != nil {
        panic(errArticle.Error())
    }
    rows, errImage := db.Query("SELECT image_name FROM images WHERE article_uuid  = ?", article.UUID)
    if errImage != nil {
        panic(errImage.Error())
    }

    return article, rows
}

dao_test.go

func TestGetSingleArticleDao(t *testing.T) {
    db, mock, err := sqlmock.New()

    if err != nil {
        t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
    }

    defer db.Close()

    articleMockRows := sqlmock.NewRows([]string{"id", "uuid", "title", "content"}).
        AddRow("1", "bea1b24d-0627-4ea0-aa2b-8af4c6c2a41c", "test", "test")

    mock.ExpectQuery("SELECT (.+) FROM articles where id=\\?").
        WithArgs("1").
        WillReturnRows(articleMockRows)

    imageMockRows := sqlmock.NewRows([]string{"article_uuid", "image_name"}).
        AddRow("bea1b24d-0627-4ea0-aa2b-8af4c6c2a41c", "1a90696f-4fe7-48f5-81a5-ca72c129f4b0").
        AddRow("bea1b24d-0627-4ea0-aa2b-8af4c6c2a41c", "3d997272-468f-4b66-91db-00c39f0ef717")

    mock.ExpectQuery("^SELECT (.+) FROM images*").
        WithArgs("bea1b24d-0627-4ea0-aa2b-8af4c6c2a41c").
        WillReturnRows(imageMockRows)

    resp := httptest.NewRecorder()
    gin.SetMode(gin.TestMode)
    ctx, _ := gin.CreateTestContext(resp)

    article, imageRows := GetSingleArticleDao(ctx, db)

    for imageRows.Next() {
        imageName := util.ImageName{}
        err := imageRows.Scan(&imageName.NAME)
        if err != nil {
            panic(err.Error())
        }
        article.IMAGENAMES = append(article.IMAGENAMES, imageName)
    }

    expectedArticle := util.Article{
        ID:      1,
        UUID:    "bea1b24d-0627-4ea0-aa2b-8af4c6c2a41c",
        TITLE:   "test",
        CONTENT: "test",
    }

    imageName1 := util.ImageName{
        NAME: "1a90696f-4fe7-48f5-81a5-ca72c129f4b0",
    }
    expectedArticle.IMAGENAMES = append(expectedArticle.IMAGENAMES, imageName1)

    imageName2 := util.ImageName{
        NAME: "3d997272-468f-4b66-91db-00c39f0ef717",
    }

    expectedArticle.IMAGENAMES = append(expectedArticle.IMAGENAMES, imageName2)

    assert.Equal(t, expectedArticle, article)
}

I expect go test -v runs without error.
But the actual is not.
Here is the error.

$ go test -v 
=== RUN   TestGetSingleArticleDao
--- FAIL: TestGetSingleArticleDao (0.00s)
panic: Query: could not match actual sql: "SELECT * FROM articles WHERE id = ?" with expected regexp "SELECT (.+) FROM articles where id=\?" [recovered]
        panic: Query: could not match actual sql: "SELECT * FROM articles WHERE id = ?" with expected regexp "SELECT (.+) FROM articles where id=\?"

goroutine 34 [running]:
testing.tRunner.func1(0xc00022c000)
        /usr/local/go/src/testing/testing.go:830 +0x392
panic(0x165a960, 0xc0001bc4a0)
        /usr/local/go/src/runtime/panic.go:522 +0x1b5
article/api/dao.GetSingleArticleDao(0xc000214160, 0xc0002180c0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
        /Users/jpskgc/article/api/dao/dao.go:26 +0x35d
article/api/dao.TestGetSingleArticleDao(0xc00022c000)
        /Users/jpskgc/article/api/dao/dao_test.go:92 +0x750
testing.tRunner(0xc00022c000, 0x1788730)
        /usr/local/go/src/testing/testing.go:865 +0xc0
created by testing.(*T).Run
        /usr/local/go/src/testing/testing.go:916 +0x35a
exit status 2
FAIL    article/api/dao 0.030s
  • 写回答

1条回答 默认 最新

  • doutou3725 2019-08-30 05:30
    关注

    This is caused by following part

        resp := httptest.NewRecorder()
        gin.SetMode(gin.TestMode)
        ctx, _ := gin.CreateTestContext(resp)
    

    I should add "id" :"1" param in ctx.
    So I changed that part into this:

        param := gin.Param{"id", "1"}
        params := gin.Params{param}
        req, _ := http.NewRequest("GET", "/article/1", nil)
        var context *gin.Context
        context = &gin.Context{Request: req, Params: params}
    
    评论

报告相同问题?

悬赏问题

  • ¥20 c语言写的8051单片机存储器mt29的模块程序
  • ¥60 求直线方程 使平面上n个点在直线同侧并且距离总和最小
  • ¥50 java算法,给定试题的难度数量(简单,普通,困难),和试题类型数量(单选,多选,判断),以及题库中各种类型的题有多少道,求能否随机抽题。
  • ¥50 rk3588板端推理
  • ¥250 opencv怎么去掉 数字0中间的斜杠。
  • ¥15 这种情况的伯德图和奈奎斯特曲线怎么分析?
  • ¥250 paddleocr带斜线的0很容易识别成9
  • ¥15 电子档案元素采集(tiff及PDF扫描图片)
  • ¥15 flink-sql-connector-rabbitmq使用
  • ¥15 zynq7015,PCIE读写延时偏大