You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go gomock测试中mockgen Return方法返回的预期值被意外修改问题

根因分析

这是Go语言切片的基础特性导致的,和gomock的Return实现无关:

  • Go的切片本质是一个包含底层数组指针、长度、容量的结构体,切片作为值传递时,仅复制结构体本身,内部的指针仍指向同一个底层数组。
  • 你在测试中直接将mock_data.Users赋值给expected并传给Return方法,mock返回的切片和expected变量共享同一底层数组。当你在GetUsers方法中修改users[0].Name时,修改直接作用到了共享的底层数组上,因此expected变量的值也会同步变更,最终断言时二者相等,测试误通过。
  • 额外隐患:你直接使用全局变量mock_data.Users,本次测试修改后,所有其他引用该全局变量的测试用例都会被数据污染。

修复方案

可选择以下任意一种方案解决问题:

  1. 给mock返回值做深拷贝
    每次传入Return的参数都是独立的新切片,避免共享底层数组:
// 示例:复制mock_data.Users生成新切片
expected := append([]model.User{}, mock_data.Users...)
ds.EXPECT().GetUsers().Return(expected)

如果切片元素包含指针类型,可以手动实现深拷贝逻辑,避免元素内部的指针共享。

  1. 修改mock数据定义,每次调用生成新实例
    把全局的切片变量改成函数,每次调用返回全新的切片,从源头避免数据共享:
// 修改mock_data定义
func GetMockUsers() []model.User {
    return []model.User{
        {
            ID:       1,
            Name:     "User A",
            Email:    "usera@gmail.com",
        },
        {
            ID:       2,
            Name:     "User B",
            Email:    "userb@gmail.com",
        },
    }
}

// 测试中使用
expected := mock_data.GetMockUsers()
ds.EXPECT().GetUsers().Return(expected)
  1. 断言时使用独立的预期值
    不要用传给mock的expected变量做断言,提前定义独立的预期结果:
// 提前定义预期返回的结果,不受mock返回值修改影响
want := []model.User{
    {ID: 1, Name: "User C", Email: "usera@gmail.com"},
    {ID: 2, Name: "User B", Email: "userb@gmail.com"},
}
assert.Equal(t, want, users)

修改后测试就会按照预期逻辑运行,当代码修改了返回值时断言会正常失败。

内容的提问来源于stack exchange,提问作者Mohsin Mushtaq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 01:36:03