当前位置: 首页 > 知识库问答 >
问题:

一次性测试用例中的DB模拟会干扰其他测试用例

方祺
2023-03-14

我有两个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案例中执行的模拟被完全忽略。

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

共有1个答案

戚宏扬
2023-03-14

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

因此,当您在第一个测试中修改修改DBRow时,您已经固有地修改了包含值在[0]处的底层数组,从AZ,当您读取dbRow时,该数组将持续存在在你的下一个测试中。在第一次测试结束时重置该值,或者在测试中使用一组不同的变量。

 类似资料:
  • 确保你的网站能够在Chrome和Android上正常运行后,你的工作并没有结束。即使Device Mode(设备模式)可以模拟一系列其他设备,如iPhone,我们鼓励你查看模拟其他浏览器的解决方案。 TL;DR 当您没有特定设备时,或想做某些事情的抽查,最好的选择是在浏览器中直接模拟设备。 设备仿真器和模拟器让你在工作站的各种设备上模拟你开发网站。 基于云的模拟器允许你跨不同平台为你的网站自动化单

  • 我试图用groovy为一个用Java编写的类编写一个测试用例。Java类(名称:helper)中有一个方法,在该方法中获取HttpClient对象并对其调用executeMethod。我试图在groovy测试用例中模拟这个HttpClient.executeMethod(),但不能正确地模拟它。 任何关于它为什么不正确嘲笑的想法。提前致谢

  • 我希望在由Capybara旋转的Chrome实例中禁用从onbeforeunload生成的对话框。我有一个非常大的测试套件,修改每次访问/刷新以包含单击“离开”确认的代码是不切实际的。 我尝试在访问和刷新之前添加,虽然这是可行的,但它共享了必须修改所有访问和刷新调用的问题。 我还检查了是否有任何ChromeCLI选项可以添加来禁用此功能,但我没有找到任何相关内容。我检查了这里:https://pe

  • 我正在使用PowerMock测试中断异常情况下的错误处理。不幸的是,这些测试有时似乎对其他测试类有一些副作用:我在一个测试类中配置的模拟似乎在另一个测试类中仍然存在。为了产生副作用,我将下面的示例简化为基本行。 让我们假设我们有一个类要测试: 以及一个使用PowerMock测试私有方法的测试类: 当我现在创建另一个测试类(在第一个测试类之后执行)时,如下所示: 我立即得到以下异常: 如果我在第一节

  • 我有一个API来获取ID、名称、数据等的列表(TestCase name

  • 我已经编写了示例CRUD方法,我已经为服务组件编写了JUnit测试用例,但得到的结果是“地址id没有找到…”当我做测试的时候。 @test public void updateAddressTest()引发ResourceNotFoundException{