用于测试HTTP交互的Go包:github.com/dnaeon/go-vcr

257 阅读2分钟

之前我介绍了 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 是一个必须的,强烈推荐