Code.2 使用httptest模拟接口测试

Test中在模拟接口测试,首先我们先实现一个最基础的Test例子:

模拟一个ping/pong的最基本请求,我们先写一个返回pongHTTP handler

import (
    "io"
    "net/http"
    "net/http/httptest"
    "testing"
)

func Pong(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(http.StatusOK)
    w.Header().Set("Content-Type", "text/plain")
    io.WriteString(w, "pong")
}

然后写测试用例:

func TestRequest(t *testing.T) {
    req, err := http.NewRequest("GET", "ping", nil)
    if err != nil {
        t.Fatal(err)
    }

    rr := httptest.NewRecorder()
    handler := http.HandlerFunc(Pong)

    handler.ServeHTTP(rr, req)

    if status := rr.Code; status != http.StatusOK {
        t.Errorf("status code %v", rr.Code)
    }

    if rr.Body.String() != "pong" {
        t.Errorf("returned %s", rr.Body.String())
    }
}

程序日志输出Pass,这个小demo正常运行了。然后我们在这个基础上,我们给请求增加一个超时时间、以及携带header头等信息

我们将请求的header头返回,处理的hander如下:

func GetUsersHandler(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(http.StatusOK)
    w.Header().Set("Content-Type", "application/json")

    output, _ := json.Marshal(r.Header)
    io.WriteString(w, string(output))
}

然后是我们的测试用例, 而且也更贴近我们的真实开发:

func TestRequest(t *testing.T) {
    req, err := http.NewRequest("GET", "/user/info", nil)
    if err != nil {
        t.Fatal(err)
    }

    // 设置header头
    req.Header.Set("uid", "10086")

    rr := httptest.NewRecorder()
    handler := http.HandlerFunc(GetUsersHandler)

    // 给请求设置1s的超时
    ctx := req.Context()
    ctx, _ = context.WithTimeout(ctx, time.Second)

    req = req.WithContext(ctx)
    handler.ServeHTTP(rr, req)

    if status := rr.Code; status != http.StatusOK {
        t.Errorf("status code %v", rr.Code)
    }
    t.Log(rr.Body.String())
}

相关推荐