之前我介绍了 github.com/h2non/gock的内容,该包用于测试HTTP请求,它的工作方式是手动模拟请求和响应,这次我们采取不同的方法,而不是这样做,我们将请求和响应都保存为固定程序,以便在未来的测试中重放它们。
使用dnaeon/go-vcr
http.RoundTripper 这个包的工作方式是通过注入作为分配给Transport 字段中使用的http.Client ,比如说。
// recorder is "github.com/dnaeon/go-vcr/recorder"
r, err := recorder.New(path.Join("fixtures", "weather_401"))
if err != nil {
t.Fatalf("failed creating recorder %s", err)
}
return &http.Client{Transport: r}, r.Stop
第一次运行这段代码时,它将创建一个名为fixtures/weather_401.yaml 的新文件,如果它不存在的话,保存所有与请求有关的信息,包括诸如查询参数和头文件,以及之后收到的响应。
保存这个文件背后的想法是为了有一个确定的方法,以便在将来运行相同的测试时得到相同的结果。dnaeon/go-vcr ,在幕后使用该文件来正确匹配请求,并返回先前保存的响应。
删除秘密
有些情况下,我们实际上是在使用真正的凭证,无论是作为HTTP头还是查询参数,dnaeon/go-vcr ,允许你删除这些,这样我们就不会泄露它们,例如。
r, err := recorder.New(path.Join("fixtures", "weather_200"))
if err != nil {
t.Fatalf("failed creating recorder %s", err)
}
cleanURL := func(u *url.URL) *url.URL {
q := u.Query()
q.Del("appid")
u.RawQuery = q.Encode()
return u
}
r.AddFilter(func(i *cassette.Interaction) error {
u, err := url.Parse(i.Request.URL)
if err != nil {
return err
}
i.URL = cleanURL(u).String()
return nil
})
r.SetMatcher(func(r *http.Request, i cassette.Request) bool {
r.URL = cleanURL(r.URL)
return cassette.DefaultMatcher(r, i)
})
return &http.Client{Transport: r}, r.Stop
在上面的情况下,我们都是。
- 删除请求中的一个查询参数,以及
- 更新匹配器以不考虑该值。
通过这样做,我们就可以在之后确定地运行我们的测试。
结论
dnaeon/go-vcr h2non/gock 在与第三方API合作时, 是非常有用的,因为在第三方API中只使用了几个字段,它允许go-vcr 未来的我们参考已保存的固定程序来做决定,比如增加对使用已知字段的支持,或者对第三方API中可能的选项做决定。
最后,dnaeon/go-vcr 是一个必须的,强烈推荐。