为了账号安全,请及时绑定邮箱和手机立即绑定

如何断言请求在同时模拟 API 时发生?

如何断言请求在同时模拟 API 时发生?

Go
慕田峪4524236 2022-10-17 10:23:40
main.gopackage mainimport (    "net/http")func SomeFeature(host, a string) {    if a == "foo" {        resp, err := http.Get(host + "/foo")    }    if a == "bar" {        resp, err := http.Get(host + "/baz"))    }    // baz is missing, the test should error!}main_test.gopackage mainimport (    "net/http"    "net/http/httptest"    "testing")func TestSomeFeature(t *testing.T) {    server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {        w.WriteHeader(200)    }))    testCases := []struct {        name     string        variable string    }{        {            name:     "test 1",            variable: "foo",        },        {            name:     "test 2",            variable: "bar",        },        {            name:     "test 3",            variable: "baz",        },    }    for _, tc := range testCases {        tc := tc        t.Run(tc.name, func(t *testing.T) {            t.Parallel()            SomeFeature(server.URL, tc.variable)            // assert that the http call happened somehow?        })    }}去游乐场:https ://go.dev/play/p/EFanSSzgnbk如何断言每个测试用例都向模拟服务器发送请求?如何断言未发送请求?同时保持测试并行/并发?
查看完整描述

1 回答

?
阿波罗的战车

TA贡献1862条经验 获得超6个赞

您可以为每个测试用例创建一个新服务器。


或者您可以使用通道,特别是通道映射,其中键是测试用例的标识符,例如


getChans := map[string]chan struct{}{}

server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

    key := strings.Split(r.URL.Path, "/")[1] // extract channel key from path

    go func() { getChans[key] <- struct{}{} }()


    w.WriteHeader(200)

}))

向测试用例添加通道键字段。这将被添加到主机的 URL 中,然后处理程序将提取密钥,如上所示,以获取正确的频道。还要添加一个字段来指示是否http.Get应该调用:


testCases := []struct {

    name      string

    chkey     string

    variable  string

    shouldGet bool

}{

    {

        name:      "test 1",

        chkey:     "key1"

        variable:  "foo",

        shouldGet: true,

    },

    // ...

}

在运行测试用例之前,将特定于测试用例的通道添加到地图中:


getChans[tc.chkey] = make(chan struct{})

然后使用测试用例中的通道键字段作为主机 URL 路径的一部分:


err := SomeFeature(server.URL+"/"+tc.chkey, tc.variable)

if err != nil {

    t.Error("SomeFeature should not error")

}

并检查是否http.Get被称为使用select一些可接受的超时:


select {

case <-getChans[tc.chkey]:

    if !tc.shouldGet {

        t.Error(tc.name + " get called")

    }

case <-time.Tick(3 * time.Second):

    if tc.shouldGet {

        t.Error(tc.name + " get not called")

    }

}

https://go.dev/play/p/7By3ArkbI_o


查看完整回答
反对 回复 2022-10-17
  • 1 回答
  • 0 关注
  • 102 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信