色々な方法があると思うけど、簡単な3種類をまとめておく。
テスト対象のコード
package main
import (
"net/http"
"github.com/facebookgo/grace/gracehttp"
"github.com/sebest/xff"
"goji.io"
"goji.io/pat"
"golang.org/x/net/context"
)
func main() {
mux := goji.NewMux()
mux.HandleC(pat.New("/*"), NewMux())
err := gracehttp.Serve(&http.Server{Addr: ":8080", Handler: mux})
if err != nil {
panic(err)
}
}
func NewMux() *goji.Mux {
mux := goji.NewMux()
mux.Use(xff.Handler)
mux.HandleFuncC(pat.Get("/:name"), Hello)
return mux
}
func Hello(ctx context.Context, w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, " + pat.Param(ctx, "name") + "\nRemote Address: " + r.RemoteAddr))
}
テストコード
その1: 関数に対してテスト
普通に関数に対してテストを行う。
特に難しいことは、していない。
func TestHello(t *testing.T) {
t.Parallel()
ctx := context.WithValue(context.Background(), pattern.Variable("name"), "john")
req, err := http.NewRequest("", "", nil)
require.NoError(t, err)
resp := httptest.NewRecorder()
Hello(ctx, resp, req)
require.Equal(t, http.StatusOK, resp.Code)
require.Contains(t, resp.Body.String(), "Hello, john")
require.NotContains(t, resp.Body.String(), "127.0.0.1")
}
その2: Multiplexer に対してテスト
Routing とか、 Middleware とかテストしたい時は、こっちの方が適切だと思う。
func TestUsersMultiplexer(t *testing.T) {
t.Parallel()
mux := NewMux()
req, err := http.NewRequest("GET", "/john", nil)
require.NoError(t, err)
resp := httptest.NewRecorder()
mux.ServeHTTP(resp, req)
require.Equal(t, http.StatusOK, resp.Code)
require.Contains(t, resp.Body.String(), "Hello, john")
require.NotContains(t, resp.Body.String(), "127.0.0.1")
}
その3: Server を立ち上げてのテスト
E2E 的なテストをしたい時や、 RemoteAddr を用いている場合は、こちらの方法が良い。
func TestServer(t *testing.T) {
t.Parallel()
ts := httptest.NewServer(NewMux())
defer ts.Close()
resp, err := http.Get(ts.URL + "/john")
require.NoError(t, err)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
require.NoError(t, err)
bodyStr := string(body)
require.Equal(t, http.StatusOK, resp.StatusCode)
require.Contains(t, bodyStr, "Hello, john")
require.Contains(t, bodyStr, "127.0.0.1")
}
他にも良い方法あったら、コメント下さい。