Go에서 http 클라이언트 조롱하기

9929 단어 gotddtesting
이동 중에 http 클라이언트를 가로채야 하는 경우 httptest 할 수 있는 기능을 제공합니다. httptest.NewServer 테스트 케이스에서 제어할 수 있는 임시 서버를 설정할 수 있습니다.

이 함수를 httptest.NewServer를 사용하는 단위 테스트를 작성하는 예로 사용할 것입니다.

func topPostOnSubreddit(r string) (string, error) {
    resp, err := http.Get(fmt.Sprintf("https://reddit.com/r/%s", r))
    if err != nil {
        return "", err
    }
    defer resp.Body.Close()

    dec := json.NewDecoder(resp.Body)
    var data redditData
    err = dec.Decode(&data)
    if err != nil {
        return "", err
    }

    top := findTopPost(data)
    return top["title"].(string), nil
}


리팩터링



이것을 리팩토링하여 단위 테스트에서 httptest.NewServer를 사용할 수 있도록 합니다. 필요한 변경 사항은 ...

http 클라이언트의 인스턴스를 전달해야 합니다.




func topPostOnSubreddit(client *http.Client, r string) (string, error) {
    req, err := http.NewRequest("GET", fmt.Sprintf("https://reddit.com/r/%s", r), nil)
    if err != nil {
        return "", err
    }
    resp, err := client.Do(req)
    // ...
}


URL의 기본은 호출자가 구성할 수 있어야 합니다.




func topPostOnSubreddit(client *http.Client, fullUrl string) (string, error) {
    req, err := http.NewRequest("GET", fullUrl, nil)
    if err != nil {
        return "", err
    }
    resp, err := client.Do(req)
    // ...
}


테스트 케이스 작성



반환된 테스트 서버에는 함수에 전달할 수 있는 클라이언트와 URL이 모두 있습니다. 함수가 클라이언트를 사용하면 테스트 케이스에서 정의한 handlerFunc가 호출됩니다. 이를 통해 런타임에 고정 데이터를 주입하여 단위 테스트 동작을 제어할 수 있습니다.

func TestTopPostOnSubreddit(t *testing.T) {
    server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        enc := json.NewEncoder(w)
        // this is where your test fixture goes
        testData := redditData{}
        err := enc.Encode(&testData)
        require.NoError(t, err)
    }))
    t.Cleanup(server.Close)

    url := fmt.Sprintf("%s/r/android.json", server.URL)
    top, err := topPostOnSubreddit(server.Client(), url)
    require.NoError(t, err)
    require.Equal(t, "foobar", top)
}


즐거운 테스트!

좋은 웹페이지 즐겨찾기