Gock
Contents
Gock:
开发项目的过程中总会遇到要调用依赖方接口的情况,如果依赖方的API接口还没有开发好,通常我们会先约定好API接口的请求参数、响应结构和各类错误对应的响应码,再按照约定好请求和响应进行开发。有些情况在开发阶段不能直接调用,因此就需要进行对依赖的api进行mock
gock 是 Go 生态下一个提供无侵入 HTTP Mock 的工具,用来在单元测试中Mock API 的调用,即不对要请求的API发起真正的调用,而是由gock拦截到请求后返回我们指定的Mock响应。
它是如何模拟的
- 用 http.DefaultTransport或自定义http.Transport拦截的任何 HTTP 请求流量
- 将传出的 HTTP 请求与按 FIFO 声明顺序定义的 HTTP 模拟期望池匹配。
- 如果至少有一个模拟匹配,它将被用来组成模拟 HTTP 响应。
- 如果没有匹配到的mock,则解析请求报错,除非启用了真实网络模式,在这种情况下,将执行真实的HTTP请求。
go get -u github.com/h2non/gock
示例
func TestHttpc(t *testing.T) {
defer gock.Off()
domain := "https://github.com"
apiPath := "/get"
apiURL := fmt.Sprintf("%v%v", domain, apiPath)
// Mock 对 https://httpbin.rs/get 的 GET 请求
gock.New(domain).
Get(apiPath).
Reply(200).
JSON(map[string]interface{}{
"mocked": true,
"headers": map[string]string{
"User-Agent": "gock",
},
"url": "https://github.com/get",
})
resp, err := http.Get(apiURL)
if err != nil {
return
}
dataB, _ := io.ReadAll(resp.Body)
fmt.Println(string(dataB))
}
如果使用里自定义的http.Client,则需要替换Transport为gock.NewTransport()
func main() {
// 启用 gock 拦截器
defer gock.Off() // 测试结束后关闭拦截
// Mock 对 https://httpbin.rs/get 的 GET 请求
gock.New("https://httpbin.rs").
Get("/get").
Reply(200).
JSON(map[string]interface{}{
"mocked": true,
"headers": map[string]string{
"User-Agent": "gock",
},
"url": "https://httpbin.rs/get",
})
req.Client().Transport = gock.NewTransport()
// 发起请求(会被 gock 拦截)
resp, err := req.Get("https://httpbin.rs/get")
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("resp: %s\n", resp.String())
}
resty mock
func TestResty(t *testing.T) {
defer gock.Off()
domain := "https://github.com"
apiPath := "/get"
apiURL := fmt.Sprintf("%v%v", domain, apiPath)
// Mock 对 https://httpbin.rs/get 的 GET 请求
gock.New(domain).
Get(apiPath).
Reply(200).
JSON(map[string]interface{}{
"mocked": true,
"headers": map[string]string{
"User-Agent": "gock",
},
"url": "https://github.com/get",
})
req := resty.New().SetTransport(gock.NewTransport()).R()
resp, err := req.Get(apiURL)
if err != nil {
return
}
fmt.Println(resp.String())
}