1. 程式人生 > >golang web開發 Handler測試利器httptest

golang web開發 Handler測試利器httptest

我們用go開發一個Web Server後,打算單元測試寫的handler函式,在不知道httptest之前,使用比較笨的方法
就是編譯執行該Web Server後,再用go編寫一個客戶端程式向該Web Server對應的route傳送資料然後解析
返回的資料。這個方法測試時非常麻煩,使用httptest來測試的話就非常簡單,可以和testing測試一起使用。

httptest基本使用方法

假設在server中handler已經寫好

http.HandleFunc("/health-check", HealthCheckHandler)

func HealthCheckHandler(w http.ResponseWriter, r *http.Request) {
    // A very simple health check.
w.WriteHeader(http.StatusOK) w.Header().Set("Content-Type", "application/json") // In the future we could report back on the status of our DB, or our cache // (e.g. Redis) by performing a simple PING, and include them in the response. io.WriteString(w, `{"alive": true}`) }

測試如下:

import (
    "net/http"
"net/http/httptest" "testing" ) func TestHealthCheckHandler(t *testing.T) { //建立一個請求 req, err := http.NewRequest("GET", "/health-check", nil) if err != nil { t.Fatal(err) } // 我們建立一個 ResponseRecorder (which satisfies http.ResponseWriter)來記錄響應 rr := httptest.NewRecorder
() //直接使用HealthCheckHandler,傳入引數rr,req HealthCheckHandler(rr, req) // 檢測返回的狀態碼 if status := rr.Code; status != http.StatusOK { t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK) } // 檢測返回的資料 expected := `{"alive": true}` if rr.Body.String() != expected { t.Errorf("handler returned unexpected body: got %v want %v", rr.Body.String(), expected) } }

然後就可以使用run test來執行測試.

如果Web Server有操作資料庫的行為,需要在init函式中進行資料庫的連線。

參考官方文件中的樣例編寫的另外一個測試程式碼:

func TestHealthCheckHandler2(t *testing.T) {
    reqData := struct {
        Info string `json:"info"`
    }{Info: "P123451"}

    reqBody, _ := json.Marshal(reqData)
    fmt.Println("input:", string(reqBody))
    req := httptest.NewRequest(
        http.MethodPost,
        "/health-check",
        bytes.NewReader(reqBody),
    )

    req.Header.Set("userid", "wdt")
    req.Header.Set("commpay", "brk")

    rr := httptest.NewRecorder()
    HealthCheckHandler(rr, req)

    result := rr.Result()

    body, _ := ioutil.ReadAll(result.Body)
    fmt.Println(string(body))

    if result.StatusCode != http.StatusOK {
        t.Errorf("expected status 200,",result.StatusCode)
    }
}

注意不同的地方
- http.NewRequest替換為httptest.NewRequest。
- httptest.NewRequest的第三個引數可以用來傳遞body資料,必須實現io.Reader介面。
- httptest.NewRequest不會返回error,無需進行err!=nil檢查。
- 解析響應時沒直接使用ResponseRecorder,而是呼叫了Result函式。

結合context使用

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

    rr := httptest.NewRecorder()
    // e.g. func GetUsersHandler(ctx context.Context, w http.ResponseWriter, r *http.Request)
    handler := http.HandlerFunc(GetUsersHandler)

    // Populate the request's context with our test data.
    ctx := req.Context()
    ctx = context.WithValue(ctx, "app.auth.token", "abc123")
    ctx = context.WithValue(ctx, "app.user",
        &YourUser{ID: "qejqjq", Email: "[email protected]"})

    // Add our context to the request: note that WithContext returns a copy of
    // the request, which we must assign.
    req = req.WithContext(ctx)
    handler.ServeHTTP(rr, req)

    // Check the status code is what we expect.
    if status := rr.Code; status != http.StatusOK {
        t.Errorf("handler returned wrong status code: got %v want %v",
            status, http.StatusOK)
    }
}

參考

推薦乾貨滿滿的技術專欄
這裡寫圖片描述

這裡寫圖片描述[toc]

相關推薦

golang web開發 Handler測試利器httptest

我們用go開發一個Web Server後,打算單元測試寫的handler函式,在不知道httptest之前,使用比較笨的方法 就是編譯執行該Web Server後,再用go編寫一個客戶端程式向該Web Server對應的route傳送資料然後解析 返回的

基於gin的golang web開發:認證利器jwt

JSON Web Token(JWT)是一種很流行的跨域認證解決方案,JWT基於JSON可以在進行驗證的同時附帶身份資訊,對於前後端分離專案很有幫助。 ``` eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6I

web前端自動化測試利器puppeteer介紹

web前端自動化測試利器puppeteer介紹 Intro Chrome59(linux、macos)、 Chrome60(windows)之後,Chrome自帶headless(無介面)模式很方便做自動化測試或者爬蟲。但是如何和headless模式的Chrome互動則是一個問題。通過啟動Chrome時的

.NET進行客戶端Web開發又一利器 - Ant Design Blazor

你好,我是Dotnet9,繼上篇介紹[Bootstrap風格的BlazorUI元件庫](https://mp.weixin.qq.com/s/Prpf7S5vTRg1fqLkUYmFKQ)後,今天我來介紹另一款Blazor UI元件庫:一套基於 Ant Design 和 Blazor 的企業級元件庫。 本文

基於gin的golang web開發:路由

Gin是一個用Golang編寫的HTTP網路框架。它的特點是類似於Martini的API,效能更好。在golang web開發領域是一個非常熱門的web框架。 #### 啟動一個Gin web伺服器 使用下面的命令安裝Gin ``` go get -u github.com/gin-gonic/gin `

基於gin的golang web開發:路由二

在[基於gin的golang web開發:路由][1]中我們介紹了Gin的路由和一些獲取連結中引數的方法,本文繼續介紹其他獲取引數的方法。 #### 檔案上傳 在web開發中檔案上傳是一個很常見的需求,下面我們來看一下基於Gin的檔案上傳。 ```golang func main() { router :

基於gin的golang web開發:模型繫結

在前兩篇文章介紹路由的時候,我們瞭解到gin可用通過類似DefaultQuery或DefaultPostForm等方法獲取到前端提交過來的引數。引數不多的情況下也很好用,但是想想看,如果介面有很多個引數的時候再用這種方法就要呼叫很多次獲取引數的方法,本文將介紹一種新的接收引數的方法來解決這個問題:模型繫結。

基於gin的golang web開發:模型驗證

Gin除了模型繫結還提供了模型驗證功能。你可以給欄位指定特定的規則標籤,如果一個欄位用binding:"required"標籤修飾,在繫結時該欄位的值為空,那麼將返回一個錯誤。開發web api的時候大部分引數都是需要驗證的,比如email引數要驗證是否是郵箱格式、phone引數要驗證是否是手機號格式等等,使

基於gin的golang web開發:訪問mysql資料庫

web開發基本都離不開訪問資料庫,在Gin中使用mysql資料庫需要依賴mysql的驅動。直接使用驅動提供的API就要寫很多樣板程式碼。你可以找到很多擴充套件包這裡介紹的是jmoiron/sqlx。另外還有一個用來處理空值的包guregu/null。 ``` go get github.com/go-sql

基於gin的golang web開發:使用資料庫事務

在前文介紹訪問資料庫時介紹了```github.com/jmoiron/sqlx```包,本文基於這個包使用資料庫事務。 ### defer 在使用資料庫事務之前,首先需要了解go語言的defer關鍵字。defer是go語言的延遲執行語句,defer後面的語句會被go進行延遲處理,在函式即將結束的時候,d

基於gin的golang web開發:中介軟體

gin中介軟體(middleware)提供了類似於面向切面程式設計或路由攔截器的功能,可以在請求前和請求之後新增一些自定義邏輯。實際開發中有很多場景會用到中介軟體,例如:許可權驗證,快取,錯誤處理,日誌,事務等。 #### 使用中介軟體 gin的中介軟體分為三類:全域性中介軟體、路由中介軟體、分組路由中介

基於gin的golang web開發:整合swagger

在前後端分離的專案維護一份完整且及時更新的api文件會極大的提高我們的工作效率,傳統專案中介面文件都是由後端開發手寫的,這種文件很難保證及時性,久而久之便失去了參考意義。swagger給我們提供了一種新的維護文件的方式,在gin中只需要編寫一些註釋即可生成一份可互動的介面文件。 ``` go get -u

基於gin的golang web開發:永遠不要相信使用者的輸入

作為後端開發者我們要記住一句話:“永遠不要相信使用者的輸入”,這裡所說的使用者可能是人,也可能是另一個應用程式。“永遠不要相信使用者的輸入”是安全編碼的準則,也就是說,任何輸入的內容在驗證無害之前都是有害的。很多應用程式的安全漏洞都和使用者輸入有關,比如SQL注入漏洞。 我們可以通過引數驗證、sql語句過濾

基於gin的golang web開發:docker

Golang天生適合執行在```docker```容器中,這得益於:```Golang```的靜態編譯,當在編譯的時候關閉```cgo```的時候,可以完全不依賴系統環境。 ### 一些基礎 測試容器時我們經常需要進入容器檢視執行情況,以下命令啟動一個centos容器並進入bash互動環境。 ``` doc

基於gin的golang web開發:Gin技術拾遺

本文是對前幾篇文章的一些補充,主要包含兩部分:單元測試和實際專案中使用路由的小問題。 ### 拾遺1:單元測試 Golang單元測試要求程式碼檔案以```_test```結尾,單元測試方法以```Test```開頭,引數為*testing.T型別。以下是一個計算hash值的工具包和對應的單元測試。 has

基於gin的golang web開發:服務間呼叫

微服務開發中服務間呼叫的主流方式有兩種HTTP、RPC,HTTP相對來說比較簡單。本文將使用 ```Resty``` 包來實現基於HTTP的微服務呼叫。 ### Resty簡介 ```Resty``` 是一個簡單的HTTP和REST客戶端工具包,簡單是指使用上非常簡單。Resty在使用簡單的基礎上提供了非常

基於gin的golang web開發:實現使用者登入

前文分別介紹過了[Resty][1]和[gin-jwt][2]兩個包,```Resty```是一個HTTP和REST客戶端,```gin-jwt```是一個實現了JWT的Gin中介軟體。本文將使用這兩個包來實現一個簡單的使用者登入功能。 ### 環境準備 實現登入功能之前要提前準備一個用於查詢使用者是否存

關於移動端web開發的真機測試

install 相對 同步 css 響應 .html http bsp 關於 五月已經過去一大半了,心情不太好,因為太困沒狀態,所以剛剛去跑了好幾圈,心情終於沒那麽郁悶了,來吧,今天要記錄的是在做移動端網頁時如何真機測試。 網上方法有很多,我就掌握一個就夠了<攤手&g

Web開發典藏大系:Web性能測試實戰詳解 PDF掃描版

場景 測試基礎 學生 應用 測試的 runner 性能測試實例 性能測試實戰 工具 本書主要講解了大數據背景下的Web性能測試的特點和方法,以及使用業內應用非常廣泛的工具――LoadRunner 11進行性能測試的具體技術與技巧。本書理論結合實踐,講解圖文並茂,並且將I

Web開發——JavaScript庫(測試jQuery)

object 屬性設置 get 不同的 strong cti Language htm 選擇   測試 JavaScript 框架庫 - jQuery   jQuery庫下載:https://jquery.com/ 1、引用 jQuery   如需測試 JavaScript