
Web开发人员的工作很大一部分涉及API调用,无论是与合作伙伴系统集成还是与供应商集成。
编写测试是开发流程中不可或缺的一部分。测试确保代码按预期工作,避免在生产环境中出现意外情况。 熟练掌握API测试对于合格的软件工程师至关重要。本文将介绍几种简化API功能测试的技术。
首先,我们需要构建一个待测试的服务。这是一个简单的例子:我们调用Pokédex API(受Pokémon TCG Pocket的启发)并列出现有的宝可梦。
<code class="go">package main
import (
"encoding/json"
"fmt"
"net/http"
)
type RespBody struct {
Results []Pokemon `json:"results"`
}
type Pokemon struct {
Name string `json:"name"`
}
const URL = "https://pokeapi.co"
func main() {
pkms, err := FetchPokemon(URL)
if err != nil {
fmt.Println(err)
return
}
for _, pkm := range pkms {
fmt.Println(pkm.Name)
}
}
func FetchPokemon(u string) ([]Pokemon, error) {
r, err := http.Get(fmt.Sprintf("%s/api/v2/pokemon", u))
if err != nil {
return nil, err
}
defer r.Body.Close()
resp := RespBody{}
err = json.NewDecoder(r.Body).Decode(&resp)
if err != nil {
return nil, err
}
return resp.Results, nil
}</code>httptest
httptest是Go语言自带的包。它允许在测试中创建模拟服务器。其主要优点是不需要引入外部依赖。但它不会自动拦截请求。
<code class="go">package main
import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
)
func Test_httptest(t *testing.T) {
j, err := json.Marshal(RespBody{Results: []Pokemon{{Name: "charizard"}}})
assert.Nil(t, err)
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v2/pokemon" {
t.Errorf("expected to request '/api/v2/pokemon', got: %s", r.URL.Path)
}
w.WriteHeader(http.StatusOK)
w.Write([]byte(j))
}))
defer server.Close()
p, err := FetchPokemon(server.URL)
assert.Nil(t, err)
assert.Equal(t, p[0].Name, "charizard")
}</code>Mocha
Mocha是一个受Nock和Wires启发的库。一个有趣的功能是能够验证模拟是否被调用。与httptest类似,它也不会自动拦截请求。
<code class="go">package main
import (
"encoding/json"
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"github.com/vitorsalgado/mocha/v3"
"github.com/vitorsalgado/mocha/v3/expect"
"github.com/vitorsalgado/mocha/v3/reply"
)
func Test_mocha(t *testing.T) {
j, err := json.Marshal(RespBody{Results: []Pokemon{{Name: "charizard"}}})
assert.Nil(t, err)
m := mocha.New(t)
m.Start()
scoped := m.AddMocks(mocha.Get(expect.URLPath("/api/v2/pokemon")).
Reply(reply.OK().BodyString(string(j))))
p, err := FetchPokemon(m.URL())
fmt.Println(m.URL())
assert.Nil(t, err)
assert.True(t, scoped.Called())
assert.Equal(t, p[0].Name, "charizard")
}</code>Gock
Gock是另一个不错的选择,它也是一个受Nock启发的库,具有简洁易用的API。它能够拦截任何
http.Client发出的HTTP请求,并提供验证模拟调用的机制。如果模拟不存在,则返回错误;如果启用实际网络模式,则请求正常进行。
<code class="go">package main
import (
"encoding/json"
"testing"
"github.com/h2non/gock"
"github.com/stretchr/testify/assert"
)
func Test_gock(t *testing.T) {
defer gock.Off()
j, err := json.Marshal(RespBody{Results: []Pokemon{{Name: "charizard"}}})
assert.Nil(t, err)
gock.New("https://pokeapi.co").
Get("/api/v2/pokemon").
Reply(200).
JSON(j)
p, err := FetchPokemon(URL)
assert.Nil(t, err)
assert.Equal(t, p[0].Name, "charizard")
}</code>apitest
最后,apitest是一个受Gock启发的库,具有丰富的匹配器和功能。它甚至允许生成HTTP调用的序列图。一个很酷的特性是它有一个很棒的网站,其中包含示例。
<code class="go">package main
import (
"encoding/json"
"net/http"
"testing"
"github.com/steinfletcher/apitest"
"github.com/stretchr/testify/assert"
)
func Test_APItest(t *testing.T) {
j, err := json.Marshal(RespBody{Results: []Pokemon{{Name: "Charizard"}}})
assert.Nil(t, err)
defer apitest.NewMock().
Get("https://pokeapi.co/api/v2/pokemon").
RespondWith().
Body(string(j)).
Status(http.StatusOK).
EndStandalone()()
p, err := FetchPokemon(URL)
assert.Nil(t, err)
assert.Equal(t, p[0].Name, "Charizard")
}</code>总结
我认为没有哪个库绝对优于其他库,选择取决于你的偏好和项目需求。如果你不想引入额外的依赖,并且不介意手动编写匹配器,那么httptest是一个不错的选择。如果你需要更丰富的API或更全面的功能,可以考虑其他库。 我个人非常喜欢apitest,并推荐在团队中使用它,因为它功能非常全面。
更多示例请访问[链接] (此处应插入实际链接)。
以上就是以最佳方式对API进行测试的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号