sqlmock:期望值不匹配完全相同的查询

问题描述

我无法获得匹配的比赛。我复制并粘贴了相同的查询,它甚至没有任何需要转义的字符。

我有以下代码

 query := "SELECT id,user_id,name,description,created_at,updated_at FROM products"

 settings := config.GetSettings()

 if limit == 0 {
     limit = settings.MaxElementsPerPagination
 }

 stmt,err := db.Prepare(query)
 if err != nil {
     err = fmt.Errorf("Failed to prepare the select products statement: %v",err)
     return
 }
 defer stmt.Close()

 rows,err := stmt.Query()
 if err != nil {
     if errors.Is(err,sql.Errnorows) {
         err = fmt.Errorf("Failed to select products: %w",errs.ErrNotExistentObject)
         return
     }

     err = fmt.Errorf("Failed to select products: %v",err)
     return
 }

 var product models.Product

 for rows.Next() {
     err = rows.Scan(
         &product.ID,&product.UserID,&product.Name,&product.Description,&product.CreatedAt,&product.UpdatedAt,)
     if err != nil {
         err = fmt.Errorf("Failed to scan product: %v",err)
         return
     }

     products = append(products,product)
 }

这是我的测试代码

    // Setup database
    db,mock,err := sqlmock.New()
    assert.Nil(t,err)

    database.New(db)
   
   // Without Regex
    mock.ExpectQuery("SELECT id,updated_at FROM products")
   // With Regex
    // mock.ExpectQuery("SELECT (.+) FROM `products`")

   // I try it with rows

   // rows := sqlmock.NewRows([]string{"id","user_id","name","description","created_at","updated_at"})

   // rows.AddRow(1,1,"TV Monitor","Monitor for TV",time.Now(),time.Now())
   // rows.AddRow(2,"Router","Awesome router",nil)

   // Without Regex
    // mock.ExpectQuery("SELECT id,updated_at FROM products").
   //     WillReturnRows(rows)
   // With Regex
   // mock.ExpectQuery("SELECT (.+) FROM `products`").
   //     WillReturnRows(rows)

    // Setup server
    e := echo.New()
    req := httptest.NewRequest(http.MethodGet,"/",nil)
    req.Header.Set(echo.HeaderContentType,echo.MIMEApplicationjsON)
    rec := httptest.NewRecorder()
    c := e.NewContext(req,rec)

    if assert.NoError(t,handlers.GetProducts(c)) {
        assert.Equal(t,http.StatusOK,rec.Code)
        assert.Equal(t,"pong",rec.Body.String())
    }

    assert.Nil(t,mock.ExpectationsWereMet())

我一直在寻找各种教程,但是没有很多sqlmock示例。我从未使用过它,也不明白为什么这行不通。

解决方法

为什么要模拟SQL查询?最好编写一个真实的集成测试来检查真实数据库的查询。对于为业务逻辑而不是为数据库交互编写单元测试,模拟是一个很好的选择。