定义
Stub(桩)是 Test Double(测试替身)的重要类型。
Stub(桩)是用于替代真实依赖,但会返回“固定的、预设的”结果的对象。
Stub 是一种测试替身,用来替代真实依赖,返回预设的、固定的数据,使单元测试可控、快速、可靠。
用途
- 控制依赖的返回结果:数据库查询、三方 API 返回、RPC 结果……
- 模拟各种测试场景:查询成功、查询失败、超时、无数据…..
- 让单元测试更快、更稳定、更可控:不用访问真实网络 / 数据库,执行速度飞快。
示例
假设有如下函数
1 2 3 4 5 6 7
| func GetUserNameByID(repo UserRepository,id int)string{ user,err:=repo.FindByID(id) if err!=nil{ return "unknown" } return user.Name }
|
可以自由控制返回的数据,Stub实现为:
1 2 3 4 5 6 7 8 9 10 11
| type StubUserRepository struct{ users map[int]User err error }
func (s StubUserRepository) FindByID(id int)(User ,error){ if s.err!=nil{ return User{},s.err } return s.users[id],nil }
|
Stub的单元测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| func TestGetUserNameByID_Success(t *testing.T){ stubRepo:=StubUserRepository{ users:map[int]User{ 1:{ID:1,Name:"Alice"}, }, }
name:=GetUserNameByID(stubRepo,1)
if name!="Alice"{ t.Error("expected Alice,got %s",name) } }
func TestGetUserNameByID_Error(t *testing.T){ stubRepo:=StubUserRepository{ err:=errors.New("db error"), }
name:=GetUserNameByID(stubRepo,1)
if name!="unknown"{ t.Errorf("expected unknown,got %s",name) } }
|