2016-11-18 67 views
2

我有類似下面的一組請求處理程序:如何測試Golang中的http請求處理程序?

func GetProductsHandler(w http.ResponseWriter, req *http.Request) { 
    defer req.Body.Close() 
    products := db.GetProducts() 

    // ... 
    // return products as JSON array 
} 

如何測試他們以正確的方式?我應該將模擬的ResponseWriter和Request對象發送給函數並查看結果嗎?

是否有工具可以在Go中模擬請求和響應對象以簡化流程,而無需在測試之前啓動服務器?

+3

你的意思是['httptest' package](https://golang.org/pkg/net/http/httptest/)? – JimB

+0

'http.Request'和'http.Response'都是簡單的和「完全導出」的類型,所以只需將它們設置爲任何你想要或需要的。不需要工具或「嘲笑」。 – Volker

+0

https://golang.org/pkg/net/http/httptest/#example_ResponseRecorder – dm03514

回答

3

Go提供了一個用於測試處理程序的模擬編寫器。標準庫文檔提供了一個例子:

package main 

import (
    "fmt" 
    "net/http" 
    "net/http/httptest" 
) 

func main() { 
    handler := func(w http.ResponseWriter, r *http.Request) { 
     http.Error(w, "something failed", http.StatusInternalServerError) 
    } 

    req := httptest.NewRequest("GET", "http://example.com/foo", nil) 
    w := httptest.NewRecorder() 
    handler(w, req) 

    fmt.Printf("%d - %s", w.Code, w.Body.String()) 
} 

我認爲有一個全局依賴(db)拋出一個扳手插入乾淨的單元測試。使用去你的測試可以重新分配一個值,掩蓋,全球價值db

另一種策略(我的首選)是打包處理的結構,其中有一個db屬性..

type Handlers struct { 
    db DB_INTERFACE 
} 

func (hs *Handlers) GetProductsHandler(w http.ResponseWriter, req *http.Request) {...} 

這樣,你的測試實例化一個Handlers與存根db對象,這將使你創建IO免費單元測試。

+0

答案中提到的「標準庫文檔」可以在這裏找到:https://golang.org/pkg/net/http/ httptest / – Adrian