golang单元测试之gomock、gomonkey

1:gomock 为官方开发的工具:https://github.com/golang/mock
主要目的是用来mock interface的,自动生成一个同样的实现,这样在测试的时候不用依赖真实的对象
特别像连接一些外部资源的时候比较好用。

2:gomonkey https://github.com/agiledragon/gomonkey 一个注入工具
可以注入函数、外部对象的方法。

原始代码,大致:

func (ci *CheckIP) CheckAllowIP(r *http.Request) (msg string, code int) {
	msg, code = "", 0
	ip := common.GetClientIP(r, Conf.Server.ClientIPMode)
	redisConn := RedisPool.Get()
	defer redisConn.Close()
	result, _ := redis.String(redisConn.Do("GET", ip))
	if result != "" {
		code = 400
		msg = "exist"
	}
	return
}

注入方法:

//gotests 生成的代码
func TestCheckIP_CheckAllowIP(t *testing.T) {
for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            ci := &CheckIP{
                ip: tt.fields.ip,
            }
            //注入common.GetClientIP
            patches := gomonkey.ApplyFunc(common.GetClientIP, func(r *http.Request, _ int) string {
                return r.Header.Get("X-Forwarded-For") //GetClientIP为一个外部包的函数
            })
            defer patches.Reset()
            //注入redis
            patchesRedis := gomonkey.ApplyMethod(reflect.TypeOf(RedisPool), "Get", func(_ *redis.Pool) redis.Conn {
                return mock.RedisConn{}//注入redisPool是一个外部struct,这边mock.RedisConn 是人肉redis.Conn的实现
//也可以用gomock来生成
            })
            defer patchesRedis.Reset()
            gotMsg, gotCode := ci.CheckAllowIP(tt.args.r)
            if gotMsg != tt.wantMsg {
                t.Errorf("CheckIP.CheckAllowIP() gotMsg = %v, want %v", gotMsg, tt.wantMsg)
            }
            if gotCode != tt.wantCode {
                t.Errorf("CheckIP.CheckAllowIP() gotCode = %v, want %v", gotCode, tt.wantCode)
            }
        })
    }
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注