首頁 > 後端開發 > Golang > 主體

gin 的 Context.Redirect 的單元測試適用於 GET 回應代碼,但不適用於 POST 回應代碼 (golang)

WBOY
發布: 2024-02-10 19:27:08
轉載
1155 人瀏覽過

gin 的 Context.Redirect 的单元测试适用于 GET 响应代码,但不适用于 POST 响应代码 (golang)

在使用Go語言編寫Web應用程式時,我們經常會用到gin框架來處理HTTP請求和回應。在進行單元測試時,我們需要對程式碼進行覆蓋測試,以確保程式碼的品質和穩定性。然而,針對gin的Context.Redirect方法的單元測試在處理GET請求時非常適用,但在處理POST請求時卻不太適用。在本文中,php小編蘋果將會詳細解釋為什麼這個問題會出現,並提供一些解決方案來進行POST請求的單元測試。

問題內容

我希望我的伺服器將特定端點重定向到另一台伺服器。這個端點可以是 getted 或 posted。在這兩種情況下,http 回應碼都應為 302。如果我在此程式碼上使用 curl ,它確實在兩種情況下都顯示回應代碼 302,並且 curl -l 正確遵循重定向。哇哦。

但是

我的單元測試使用httptest.newrecorder()來捕獲訊息,但它僅適用於get,不適用於post。因此,當我知道實際的重定向正在工作時,我需要弄清楚如何讓單元測試工作。失敗測試顯示http回應碼是200而不是302(http.statusfound)。

$ go run foo.go
post code 200
get code 302
登入後複製

這是獨立測試。

package main

import (
    "net/http"
    "net/http/httptest"
    "github.com/gin-gonic/gin"
)

func main() {
    gin.setmode(gin.releasemode)
    {
        w := httptest.newrecorder()
        context, _ := gin.createtestcontext(w)
        context.request = httptest.newrequest("post", "http://localhost:23632/foobar", nil)
        context.redirect(http.statusfound, "http://foobar.com")

        print("post code ",w.code,"\n")
    }

    {
        w := httptest.newrecorder()
        context, _ := gin.createtestcontext(w)
        context.request = httptest.newrequest("get", "http://localhost:23632/foobar", nil)
        context.redirect(http.statusfound, "http://foobar.com")

        print("get code ",w.code,"\n")
    }
}
登入後複製

當我在實際應用程式(未顯示)上執行 curl post 時,我發現它正在工作:

curl -v -XPOST localhost:23632/foobar
* About to connect() to localhost port 23632 (#0)
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 23632 (#0)
> POST /foobar HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:23632
> Accept: */*
>
< HTTP/1.1 302 Found
< Location: http://foobar.com
< Vary: Origin
< Date: Tue, 23 May 2023 22:38:42 GMT
< Content-Length: 0
<
* Connection #0 to host localhost left intact
登入後複製

解決方法

tl;dr

解決方法是在 context.redirect 之後明確呼叫 context.writer.writeheadernow

說明

這是使用從 gin.createtestcontext 傳回的 gin 上下文的一個極端情況。

對於get 請求,gin 最終會呼叫http.redirect ,它將向回應寫入一個簡短的html 正文(類似於<a href="http://foobar. com">found</a> ),從而導致要寫入回應的狀態碼。

對於 post 請求,http.redirect 不會寫入短 html 正文,且狀態碼沒有機會寫入回應。

請參考http 的實作.重定向。根據原始碼,如果之前設定了content-type header,那麼get請求也會出現相同的問題:

{
    w := httptest.newrecorder()
    context, _ := gin.createtestcontext(w)
    context.request = httptest.newrequest("get", "http://localhost:23632/foobar", nil)
+   context.header("content-type", "text/html")
    context.redirect(http.statusfound, "http://foobar.com")
    print("get code ", w.code, "\n")
  }
登入後複製

解決方法是明確呼叫 context.writer.writeheadernow

{
    w := httptest.NewRecorder()
    context, _ := gin.CreateTestContext(w)
    context.Request = httptest.NewRequest("POST", "http://localhost:23632/foobar", nil)
    context.Redirect(http.StatusFound, "http://foobar.com")
+   context.Writer.WriteHeaderNow()

    print("POST code ", w.Code, "\n")
  }
登入後複製

gin 本身使用相同的解決方法。請參閱 testcontextrenderredirectwithrelativepath

真正的伺服器應用程式不會遇到相同的問題,因為(*engine).handlehttprequest 將為我們呼叫writeheadernow (請參閱原始碼)。這就是為什麼我稱其為“極端情況”而不是“錯誤”。

以上是gin 的 Context.Redirect 的單元測試適用於 GET 回應代碼,但不適用於 POST 回應代碼 (golang)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:stackoverflow.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板