測試 Go 語言 Web 應用程式

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。![image](https://raw.githubusercontent.com/studygolang/gctt-images/master/testing-web-app/cover.jpg)我利用閑暇的時間嘗試著用 Go 來寫一個網站小應用。在 Go 標準庫中有一些非常棒的包可以在 Web 應用程式開發中使用並且我非常喜歡使用它們。實際上,在 Go 官方的 wiki 中有一個編寫 Web 應用程式的小教程。但是,卻沒有提及如何用標準庫去測試 Web 應用程式,而且也沒有搜尋到比較好的一個方案。本著試一試的心態在我自己的項目中做了一些嘗試,我發現了測試 Go 語言中 Web 應用程式的關鍵,就是通過使用進階的函數來實現依賴注入。## 依賴注入通過[依賴注入](https://en.wikipedia.org/wiki/Dependency_injection)我們希望能達到可以支援我們所有的功能要求這樣一個目標。然而,剛開始不太清楚怎麼做。大多數的教程都會像這樣寫一個 Web 應用程式:```gopackage mainimport ( "fmt" "net/http")func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])}func main() { http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil)}```來源: [編寫一個 Web 應用程式 - Golang Wiki](https://golang.org/doc/articles/wiki/)並不是說這是一個不好的處理方法,但是我們想要知道當添加一個資料庫時發生了什麼呢?或者一個外部的包要操作我們的 sessions ,像 [Gorilla Session](https://github.com/gorilla/sessions) 那樣嗎?通常,人們會執行個體化一個資料庫來管理或者操作一個全域的 session 並且將有效期間設定成一天。但這樣當你試圖測試時將會給你帶來麻煩。最好是編寫一個函數來為你建立相關的操作。```gopackage mainimport ( "fmt" "net/http" "github.com/markberger/database")type AppDatabase interface { GetBacon() string}func homeHandler(db AppDatabase) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hi there, I love %s!", db.GetBacon()) })}func main() { db := database.NewDatabase() http.HandleFunc("/", homeHandler(db)) http.ListenAndServe(":8080", nil)}```這樣是非常好的,因為這樣我們就不再需要全域變數了。而且這樣能非常輕鬆的 mocking (譯者註:用一個虛擬對象來建立以便測試的測試方法)。我們只需要實現 `GetBacon` 這個方法,就能簡單地建立一個資料庫 mock 來滿足介面的資料需求。## 測試現在我們需要一個項目來開始編寫我們的測試。關鍵是測試 `http.Handler`,用的是 [net/http/httptest](https://golang.org/pkg/net/http/httptest/) 包中的 `httptest.ResponseRecorder` 裡面的方法。```gopackage mainimport( "net/http" "net/http/httptest" "testing")type MockDd struct {}function (db MockDb) GetBacon() { return "bacon"}function TestHome(t *testing.T) { mockDb := MockDb{} homeHandle := homeHandler(mockDb) req, _ := http.NewRequest("GET", "", nil) w := httptest.NewRecorder() homeHandle.ServeHTTP(w, req) if w.Code != http.StatusOK { t.Errorf("Home page didn't return %v", http.StatusOK) }}```當然,這些代碼能很好的複用,尤其是進行 POST 請求測試時。因此,我一直在使用這些方法來進行測試操作。```gopackage mainimport ( "net/http" "net/http/httptest" "net/url" "testing")type HandleTester func( method string, params url.Values,) *httptest.ResponseRecorder// Given the current test runner and an http.Handler, generate a// HandleTester which will test its given input against the// handler.func GenerateHandleTester( t *testing.T, handleFunc http.Handler,) HandleTester { // Given a method type ("GET", "POST", etc) and // parameters, serve the response against the handler and // return the ResponseRecorder. return func( method string, params url.Values, ) *httptest.ResponseRecorder { req, err := http.NewRequest( method, "", strings.NewReader(params.Encode()), ) if err != nil { t.Errorf("%v", err) } req.Header.Set( "Content-Type", "application/x-www-form-urlencoded; param=value", ) w := httptest.NewRecorder() handleFunc.ServeHTTP(w, req) return w }}function TestHome(t *testing.T) { mockDb := MockDb{} homeHandle := homeHandler(mockDb) test := GenerateHandleTester(t, homeHandle) w := test("GET", url.Values{}) if w.Code != http.StatusOK { t.Errorf("Home page didn't return %v", http.StatusOK) }}```更多相關的詳細用法,可以[點擊](https://github.com/markberger/carton/blob/master/api/auth_test.go)查看我的小項目。如果你有更好的方法來利用標準庫進行 web 應用測試,你可以隨時進行留言或給我發 email。

via: http://markjberger.com/testing-web-apps-in-golang/

作者:Mark J. Berger 譯者:zhuCheer 校對:polaris1119

本文由 GCTT 原創編譯,Go語言中文網 榮譽推出

本文由 GCTT 原創翻譯,Go語言中文網 首發。也想加入譯者行列,為開源做一些自己的貢獻嗎?歡迎加入 GCTT!
翻譯工作和譯文發表僅用於學習和交流目的,翻譯工作遵照 CC-BY-NC-SA 協議規定,如果我們的工作有侵犯到您的權益,請及時聯絡我們。
歡迎遵照 CC-BY-NC-SA 協議規定 轉載,敬請在本文中標註並保留原文/譯文連結和作者/譯者等資訊。
文章僅代表作者的知識和看法,如有不同觀點,請樓下排隊吐槽

525 次點擊  
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.