ほぼ https://medium.com/@PurdonKyle/unit-testing-golang-http-middleware-c7727ca896ea のまんまだけど、自分用にメモ。
GolangのHTTP Middlewareというのは Goで始めるMiddleware - Qiita に紹介されているようなもの。PerlだとPlack Middleware、RubyだとRack Middlewareと概念的には同じだと思う。
HTTP Middlewareを作った時、もちろんMiddlewareもテストをしたい。
テストしたいHTTP Middleware
例えば以下のようなセキュリティ的に重要なヘッダを自動で入れてくれるHTTP Middlewareを考える。
func headerMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("X-XSS-Protection", "1; mode=block") w.Header().Set("X-Content-Type-Options", "nosniff") w.Header().Set("X-Frame-Options", "DENY") next.ServeHTTP(w, r) }) }
どうテストするか
何もしないhttp.HandlerFuncをHTTP Middlewareに渡して、それをhttptest.NewServerに渡してテストサーバを立ち上げることでテストできる。
こんな感じ。簡単ですね。
// getTestHandler returns a http.HandlerFunc for testing http middleware func getTestHandler() http.HandlerFunc { fn := func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "Test Handler") } return http.HandlerFunc(fn) } func TestHeaderMiddleware(t *testing.T) { ts := httptest.NewServer(headerMiddleware(getTestHandler())) defer ts.Close() resp, err := http.Get(ts.URL) assert.NoError(t, err) defer resp.Body.Close() assert.Equal(t, "1; mode=block", resp.Header.Get("X-XSS-Protection")) assert.Equal(t, "nosniff", resp.Header.Get("X-Content-Type-Options")) assert.Equal(t, "DENY", resp.Header.Get("X-Frame-Options")) }