Go语言如何对带接收者的私有方法做单元测试 如何mock DB依赖
带接收者的私有方法单元测试方案
Go 语言中小写开头的标识符仅支持同包内访问,要测试私有方法,只需要满足测试文件和业务源码在同一个包即可:
- 测试文件以
_test.go为后缀,和目标源码放在同一个目录下 - 测试文件的包声明和业务源码保持一致,比如这里都用
package service - 同包环境下可以直接调用
srv实例的所有私有方法,没有访问限制
测试代码示例:
package service import "testing" func TestSrv_isShare(t *testing.T) { // 注入mock DB初始化srv实例(mock方案见下文) s := &srv{ db: mockDB, } // 直接调用私有方法,同包下完全合法 gotRes, gotErr := s.isShare("exist_id") // 断言返回结果符合预期 if gotErr != nil { t.Fatalf("isShare expect no error, got %v", gotErr) } if !gotRes { t.Error("isShare expect true for exist id, got false") } }
srv 结构体DB字段的Mock注入方案
核心思路是通过依赖倒置,用接口替代具体DB类型,实现业务逻辑和具体DB实现的解耦,步骤如下:
- 抽象DB接口,替换srv的DB字段类型
将原来的具体DB类型(比如*MySQLConn、*MongoClient等)替换为仅包含业务所需方法的接口,示例:
package service // DB 抽象业务需要的DB操作接口 type DB interface { Get(id string) *Record // Record为你的业务数据类型,按需调整 } // srv 结构体的db字段改用接口类型 type srv struct { db DB }
- 实现Mock DB结构体,满足上述DB接口
你可以手写Mock实现,也可以用mockgen这类工具自动生成,手写示例:
package service // MockDB 自定义Mock实现,支持预设返回值 type MockDB struct { GetFunc func(id string) *Record } func (m *MockDB) Get(id string) *Record { return m.GetFunc(id) }
- 测试时注入Mock DB实例
初始化srv时把构造好的Mock DB实例传入即可,不需要连接真实数据库:
// 构造Mock DB,预设Get方法的返回逻辑 mockDB := &MockDB{ GetFunc: func(id string) *Record { // 按需模拟不同场景的返回值 if id == "exist_id" { return &Record{/* 填充模拟数据 */} } return nil }, } // 注入mock DB到srv实例 testSrv := &srv{db: mockDB} // 后续调用isShare方法时,就会走Mock的Get逻辑
内容的提问来源于stack exchange,提问作者lee
相关产品推荐
相关产品推荐

