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

使用 httptest 和 curl 的不同内容类型

使用 httptest 和 curl 的不同内容类型

Go
慕姐8265434 2023-06-05 19:26:30
我正在尝试这个 Go 代码package mainimport (    "github.com/gorilla/mux"    "io"    "log"    "net/http")func HealthCheckHandler(w http.ResponseWriter, r *http.Request) {    w.WriteHeader(http.StatusOK)    w.Header().Set("Content-Type", "application/json")    io.WriteString(w, `{"alive": true}`)}func main() {    router := mux.NewRouter()    router.HandleFunc("/health", HealthCheckHandler).Methods("GET")    log.Printf("running server ...")    log.Fatal(http.ListenAndServe(":8000", router))}通过这个测试package mainimport (    "net/http"    "net/http/httptest"    "testing")func TestHealthCheckHandler(t *testing.T) {    req, err := http.NewRequest("GET", "/health", nil)    if err != nil {        t.Fatal(err)    }    rr := httptest.NewRecorder()    handler := http.HandlerFunc(HealthCheckHandler)    handler.ServeHTTP(rr, req)    if status := rr.Code; status != http.StatusOK {        t.Errorf("handler returned wrong status code: got %v want %v",            status, http.StatusOK)    }    t.Logf("%v", rr.Header())    if ctype := rr.Header().Get("Content-Type"); ctype != "application/json" {        t.Errorf("content type header does not match: got %v want %v",            ctype, "application/json")    }}当我运行测试时,一切正常go test -v=== RUN   TestHealthCheckHandler--- PASS: TestHealthCheckHandler (0.00s)    handlers_test.go:24: map[Content-Type:[application/json]]PASSok          0.012s是,但是当我运行该服务并用 curl 调用它时Content-Type,是application/jsonContent-Typetext/plaincurl -v localhost:8000/health*   Trying ::1...* Connected to localhost (::1) port 8000 (#0)> GET /health HTTP/1.1> Host: localhost:8000> User-Agent: curl/7.43.0> Accept: */*>< HTTP/1.1 200 OK< Date: Thu, 14 Feb 2019 01:37:15 GMT< Content-Length: 15< Content-Type: text/plain; charset=utf-8<* Connection #0 to host localhost left intact为什么行为不同于测试和执行?
查看完整描述

2 回答

?
MMMHUHU

TA贡献1834条经验 获得超8个赞

问题是您在标题之前发送了身体。这在任何语言中都行不通——这是 HTTP 的事实,而不是 Go 的事实。


它没有被您的测试捕获的原因是您的测试实际上是在滥用ResponseRecorder;您在地图中设置字段,然后直接从该地图读取字段。测试应该只检查ResponseRecorder.Result,它旨在为您提供客户端实际收到的结果,包括在发送正文时锁定标头:


if ctype := rr.Response().Header.Get("Content-Type"); ctype != "application/json" {

    t.Errorf("content type header does not match: got %v want %v",

        ctype, "application/json")

}


查看完整回答
反对 回复 2023-06-05
?
婷婷同学_

TA贡献1844条经验 获得超8个赞

只需将您的功能更改为:


func HealthCheckHandler(w http.ResponseWriter, r *http.Request) {


    // this will cause a duplicate status header to be written

    // w.WriteHeader(http.StatusOK)


    w.Header().Set("Content-Type", "application/json")


    io.WriteString(w, `{"alive": true}`)

}


查看完整回答
反对 回复 2023-06-05
  • 2 回答
  • 0 关注
  • 113 浏览
慕课专栏
更多

添加回答

举报

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