首页 > 解决方案 > 为什么“mock.ExpectQuery”返回“没有参数”

问题描述

下面是我的单元测试文件:

func TestAddLike(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()

    rows := sqlmock.NewRows([]string{"id", "title", "body"}).
        AddRow(1, "post 1", "hello").
        AddRow(2, "post 2", "world")

    mock.ExpectQuery("SELECT (.+) FROM testmock").
        WillReturnRows(rows)

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

}

在此处输入图像描述

在此处输入图像描述

框架:<code>gin

数据库:gorm

我想写一个单元测试..

我有两个问题:

  1. 如何sqlmock.New()选择数据库?
  2. 为什么mock.ExpectQuery返回is without argument

提前致谢。

标签: unit-testinggogo-sqlmock

解决方案


  1. sqlmock.New() 如何选择数据库?

答:它不会对数据库进行实际调用。它的一个Mock意思是不是真正的数据库。

  1. 为什么 mock.ExpectQuery 返回没有参数

答案: 我没有看到对AddLike()inside的调用TestAddLike(t *testing.T)。试着把它也写进去:

func TestAddLike(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()

    rows := sqlmock.NewRows([]string{"id", "title", "body"}).
        AddRow(1, "post 1", "hello").
        AddRow(2, "post 2", "world")

    mock.ExpectQuery("SELECT (.+) FROM testmock").
        WillReturnRows(rows)
 
    AddLike() // <- Add the call to actual function here. Before mock.ExpectationsWereMet

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

}
  1. 我想检查我的数据库是否增加了

答:你不能。编写单元测试的主要目的是隔离(独立于实际的数据库调用或对某些服务器的 API 调用)函数并根据这些依赖项的输出测试函数的逻辑(例如:DB 抛出一个errorAPI调用返回不同的响应)。调用实际数据库将打破该规则。这就是集成测试发挥作用的地方。

现在,作为单元测试的一部分,您只需检查:

  • 如果将正确的SQL查询传递给 SQL 模拟
  • 返回mockDB 的响应后,验证函数的输出是否为expected

推荐阅读