mockgen 未安装或不在 path 中需手动安装并配置环境变量;-source 路径错误、接口未导出或包名不匹配会导致 interface not found;泛型和 error 位置不当易致签名不一致;参数匹配需用 assignabletotypeof 等;务必调用 finish() 且每个测试独立 controller。

mockgen 命令没找到或报错 command not found
说明 mockgen 没装,或者不在 $PATH 里。它不是 Go 自带工具,得手动安装。
- 用
go install github.com/golang/mock/mockgen@latest安装(Go 1.16+,推荐) - 装完检查:运行
mockgen -version,输出类似mockgen v1.6.0才算成功 - 如果提示
command not found,确认$GOPATH/bin在$PATH中(常见于 macOS/Linux 的~/.bash_profile或~/.zshrc) - Windows 用户注意:PowerShell 默认不读取
%GOPATH%\bin,需手动加进系统环境变量
mockgen -source 生成空文件或报错 interface not found
这是路径和包名没对上导致的最常见问题。mockgen 不会自动解析 import 路径,它只认「当前工作目录下的相对路径」或「已 go mod init 的模块路径」。
-
-source后跟的必须是 Go 源文件路径,比如./storage/user.go,不能写storage/user.go(少./会找错位置) - 文件里接口必须是 导出的(首字母大写),且不能在
main包里(mockgen 不支持main包) - 如果接口定义在别的包(如
github.com/xxx/core),别用-source,改用-package+-destination+-mock_names配合-source的替代方式:mockgen -destination mock_user.go -package mocks github.com/xxx/core UserStore,SessionManager - 报
interface not found时,先用go list -f '{{.Name}}' ./storage确认包名是否和源文件里package storage一致
生成的 mock 方法签名和原接口不一致
通常是返回值类型、error 位置或泛型没处理好。mockgen 对泛型支持有限(v1.6.0 开始支持,但仅限简单 case),且默认把所有 error 当作最后一个返回值处理。
- 如果原方法返回
(int, error),mock 生成正常;但若返回(error, int),mockgen 会误判 error 位置,导致调用时 panic —— 这时候必须用-build_flags="-tags=mock"或手动改接口,把 error 放最后 - 含泛型的接口(如
type Repo[T any] interface { Save(t T) error }),mockgen 可能直接跳过或报错;建议拆出非泛型接口再 mock,或改用 testify/mock(不推荐,破坏类型安全) - 嵌套结构体字段含未导出字段时,mockgen 生成的
EXPECT()方法可能无法链式调用 —— 检查结构体字段是否都首字母大写
测试中调用 mock 方法始终 panic: “call to mocked method XXX with unexpected arguments”
不是 mock 写错了,而是 EXPECT() 预期没设对,或参数比较逻辑不匹配。
- 默认参数比较是「全等(==)」,如果传的是指针、切片、map 或 struct,哪怕内容一样,地址不同就失败 —— 改用
gomock.AssignableToTypeOf(...)或gomock.Any() - 例如期望任意
*User,别写mock.EXPECT().Create(gomock.Eq(&u)),而要写mock.EXPECT().Create(gomock.AssignableToTypeOf(&User{})) - 忘记调
mockCtrl.Finish()会导致测试通过但实际没校验调用次数;反过来,多调一次Finish()会 panic —— 推荐用defer mockCtrl.Finish()放在测试函数开头 - 并发测试中复用同一个
*gomock.Controller会冲突,每个 test case 必须新建 controller
mockgen 本身不处理依赖注入时机、生命周期管理、或 interface 抽象是否合理。这些藏在业务代码里的设计问题,mock 生成得再快也救不了 —— 别让生成速度掩盖了接口粒度太粗、职责不清的事实。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











