登录
首页 >  Golang >  Go问答

数据库模拟在 Go 测试中会干扰其他测试用例的问题

来源:stackoverflow

时间:2024-02-16 10:36:23 118浏览 收藏

珍惜时间,勤奋学习!今天给大家带来《数据库模拟在 Go 测试中会干扰其他测试用例的问题》,正文内容主要涉及到等等,如果你正在学习Golang,或者是对Golang有疑问,欢迎大家关注我!后面我会持续更新相关内容的,希望都能帮到正在学习的大家!

问题内容

我有两个 go 测试用例,如下所示,用于测试名为 myendpoint 的 grpc 函数。

myendpoint 选择的数据库行具有 field1 == "a" 时,它应该成功,否则返回错误。

我正在使用 data-dog 的 go-sqlmock 包模拟数据库。

package mypackage_test

import (
    "github.com/DATA-DOG/go-sqlmock"
    "github.com/stretchr/testify/require"
)


type MyEntity struct {
    Id                     sql.NullInt32 `db:"id"`  
    Field1                 sql.NullString `db:"field1"`
    Field2                 sql.NullString `db:"field2"`
    Field3                 sql.NullString `db:"field3"`
}

var Columns = []string{
    "id",
    "field_1",
    "field_2",
    "field_3"
}



var dbRow = []driver.Value{int32(999), "A", "B", "C"]


func TestMyTestA(t *testing.T) {
    t.Run("Verify MyEndpoint Fails when mocked Database row has Field1 != A", func(t *testing.T) {
        api, err := getMyAPI()
        require.Nil(t, err)
        defer api.Close()

        api.DBMock.ExpectBegin()
        api.DBMock.MatchExpectationsInOrder(false)

        modifiedDBRow := dbRow
        modifiedDBRow[0] = "Z"
        api.DBMock.ExpectQuery("SELECT").
            WithArgs(int32(999)).WillReturnRows(sqlmock.NewRows(Columns).AddRow(modifiedDBRow...))
        api.DBMock.ExpectCommit()
        
        _, err = ... // Call MyEndpoint with parameter Id: int32(999)
        api.DBMock.ExpectClose()
        require.NotNil(t, err)
    })
}

func TestMyTestB(t *testing.T) {
    t.Run("Verify MyEndpoint succeeds when mocked Database row has Field1 == A", func(t *testing.T) {
        api, err := getMyAPI()
        require.Nil(t, err)
        defer api.Close()

        api.DBMock.ExpectBegin()
        api.DBMock.MatchExpectationsInOrder(false)

        api.DBMock.ExpectQuery("SELECT").
            WithArgs(int32(999)).WillReturnRows(sqlmock.NewRows(Columns).AddRow(dbRow...))
        api.DBMock.ExpectCommit()
        
        _, err = ... // Call MyEndpoint with parameter Id: int32(999)
        api.DBMock.ExpectClose()
        require.Nil(t, err)
    })
}

当我单独运行这两个测试用例时,它们都通过了。

但是当我一起运行它们时,testmytestb 失败,因为它认为 field1 ==“z”。 显然 testmytesta 正在干扰 testmytestb。为什么?

似乎在 testmytesta 案例中完成的模拟在到达 testmytestb 时仍然有效,并且我在 testmytestb 案例中所做的模拟被完全忽略。

我怎样才能独立地模拟这两个测试用例?


正确答案


这是因为在第一个测试中对 modifiedDBRow 切片的分配不正确。请记住,切片不存储任何数据,它只是描述底层数组的一部分。

因此,当您在第一个测试中修改 modifiedDBRow 时,您本质上修改了包含 [0] 处的值的基础数组,从 AZ,当您在下一个测试中读取 dbRow 时,该数组仍然存在。要么在第一次测试结束时重置值,要么在测试中使用一组不同的变量。

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>