在调用期间,mockgen 的返回方法中的预期值发生了变化

Posted

技术标签:

【中文标题】在调用期间,mockgen 的返回方法中的预期值发生了变化【英文标题】:Expected value is changed in Return Method of mockgen during its call 【发布时间】:2021-11-14 13:42:39 【问题描述】:

我是 Go 新手,最近,我正在尝试使用 gomock 包编写测试用例。我遇到了一个奇怪的问题。我正在尝试为GetUsers 编写测试用例,其 实现是

func (ctrl *HttpController) GetUsers(w http.ResponseWriter, r *http.Request) 

    users := ctrl.DS.GetUsers()
    
    // changed the name of the user
    users[0].Name = "User C"
    utility.JsonOkResponse(w, users)
 

这是我的测试功能

func TestGetUsers_Success(t *testing.T) 

    // setup mock interfaces
    ctrl, ds, _ := setup(t)

    // setup expected function calls
    expected := mock_data.Users
    ds.EXPECT().GetUsers().Return(expected)

    // create the request
    req := httptest.NewRequest("GET", "/users", nil)

    // generate router
    mux := mux.NewRouter()
    mux.HandleFunc("/users", ctrl.GetUsers)

    // create response recorder
    resp := httptest.NewRecorder()
    mux.ServeHTTP(resp, req)

    // check response contents
    assert.Equal(t, http.StatusOK, resp.Code)

    var users []model.User
    json.Unmarshal(resp.Body.Bytes(), &users)

    assert.Equal(t, expected, users)

这些是 mock_data.Users

var Users = []model.Useruser1, user2

// sample user data
var user1 = model.User
    ID:       1,
    Name:     "User A",
    Email:    "usera@gmail.com",


var user2 = model.User
    ID:       2,
    Name:     "User B",
    Email:    "userb@gmail.com",

现在,我正在尝试不同的场景以便更好地理解。因此,在这种情况下,我的测试用例应该失败(尽管它仍然通过),因为我在 GetUsers 函数中更改了用户名之一,但奇怪的是,测试用例仍然通过,当我执行 assert.Equal(t, expected, users) 时,预期的值是也更改为新用户名 User Cexpected 值是在 mockgen 的 Return 方法中作为指针传递还是我缺少一些基本的东西?

【问题讨论】:

【参考方案1】:

发生这种情况是因为当您执行expected := mock_data.Users 时,您正在制作切片头的副本,而不是底层数组,因此对第一个切片数组的更改将更改另一个。请查看此article 了解更多详情。

如果要复制切片,则需要使用内置的copy 函数,如下所示:

expected := make([]model.User, len(mock_data.Users))
copy(expected, mock_data.Users)

【讨论】:

感谢您的解释。我明白了

以上是关于在调用期间,mockgen 的返回方法中的预期值发生了变化的主要内容,如果未能解决你的问题,请参考以下文章

迭代期间无法获得单独的引用

理解片段事务期间片段的生命周期方法调用

EasyMock 为预期方法返回 Null

如何在应用启动期间触发方法? (安卓)

CustomSQLUtil 在使用 Liferay 7 进行查询检索期间获取空值

继续调用第 3 方,直到它返回 Hystrix 的预期响应