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

main.go


package main


import (

    "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.go


package main


import (

    "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

如何断言每个测试用例都向模拟服务器发送请求?

如何断言未发送请求?

同时保持测试并行/并发?


慕田峪4524236
浏览 103回答 1
1回答

阿波罗的战车

您可以为每个测试用例创建一个新服务器。或者您可以使用通道,特别是通道映射,其中键是测试用例的标识符,例如getChans := map[string]chan struct{}{}server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {&nbsp; &nbsp; key := strings.Split(r.URL.Path, "/")[1] // extract channel key from path&nbsp; &nbsp; go func() { getChans[key] <- struct{}{} }()&nbsp; &nbsp; w.WriteHeader(200)}))向测试用例添加通道键字段。这将被添加到主机的 URL 中,然后处理程序将提取密钥,如上所示,以获取正确的频道。还要添加一个字段来指示是否http.Get应该调用:testCases := []struct {&nbsp; &nbsp; name&nbsp; &nbsp; &nbsp; string&nbsp; &nbsp; chkey&nbsp; &nbsp; &nbsp;string&nbsp; &nbsp; variable&nbsp; string&nbsp; &nbsp; shouldGet bool}{&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; name:&nbsp; &nbsp; &nbsp; "test 1",&nbsp; &nbsp; &nbsp; &nbsp; chkey:&nbsp; &nbsp; &nbsp;"key1"&nbsp; &nbsp; &nbsp; &nbsp; variable:&nbsp; "foo",&nbsp; &nbsp; &nbsp; &nbsp; shouldGet: true,&nbsp; &nbsp; },&nbsp; &nbsp; // ...}在运行测试用例之前,将特定于测试用例的通道添加到地图中:getChans[tc.chkey] = make(chan struct{})然后使用测试用例中的通道键字段作为主机 URL 路径的一部分:err := SomeFeature(server.URL+"/"+tc.chkey, tc.variable)if err != nil {&nbsp; &nbsp; t.Error("SomeFeature should not error")}并检查是否http.Get被称为使用select一些可接受的超时:select {case <-getChans[tc.chkey]:&nbsp; &nbsp; if !tc.shouldGet {&nbsp; &nbsp; &nbsp; &nbsp; t.Error(tc.name + " get called")&nbsp; &nbsp; }case <-time.Tick(3 * time.Second):&nbsp; &nbsp; if tc.shouldGet {&nbsp; &nbsp; &nbsp; &nbsp; t.Error(tc.name + " get not called")&nbsp; &nbsp; }}https://go.dev/play/p/7By3ArkbI_o
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go