LoginSignup
97
65

More than 5 years have passed since last update.

Go言語のHTTPサーバのテスト事始め

Last updated at Posted at 2017-12-14

この記事は、Go2 Advent Calendar 2017の15日目の記事です。

最初に

Go言語のHTTPサーバに対してテストを実装する方法を簡単にですがご紹介したいと思います。
今回はサーバ側の実装としてechoを利用していますが、他のフレームワークを利用していても同様にテストすることが可能です。

今回のテスト対象のHTTPサーバは以下の通りです。

package main

import (
    "net/http"

    "github.com/labstack/echo"
)

const helloMessage = "Hello, World!"

func main() {
    router := NewRouter()

    router.Start(":8080")
}

func NewRouter() *echo.Echo {
    e := echo.New()

    e.GET("/hello", helloHandler)

    return e
}

func helloHandler(c echo.Context) error {
    return c.String(http.StatusOK, helloMessage)
}

HTTPリクエストをシミュレートしてテスト

HandlerFuncに対してServeHTTP(w ResponseWriter, r *Request)を使うことで実際にサーバを立ち上げずにリクエストをシミュレートすることが可能です。
httptest.NewRequest(method, target string, body io.Reader)でクライアント側をシミュレートし、httptest.NewRecorder()で生成するレコーダーでレスポンスを記録することが可能です。

package main

import (
    "net/http"
    "net/http/httptest"
    "testing"

    "github.com/stretchr/testify/assert"
)

func TestHelloHandler(t *testing.T) {
    router := NewRouter()

    req := httptest.NewRequest("GET", "/hello", nil)
    rec := httptest.NewRecorder()

    router.ServeHTTP(rec, req)

    assert.Equal(t, http.StatusOK, rec.Code)
    assert.Equal(t, helloMessage, rec.Body.String())
}

実際にHTTPリクエストを飛ばしてテスト (E2E test)

サーバ部分をhttptest.NewServer(handler http.Handler)httptest.Serverに置き換えてテストを行います。
httptest.Serverはテスト時に、net.Listen("tcp", "127.0.0.1:0")でloopbackの空いている適当なポートをListenしてくれます。
尚、Listenしたいポートを固定化したい場合はgo test -httptest.serve=127.0.0.1:8000と実行することで固定化することも可能です。

package main

import (
    "io/ioutil"
    "net/http"
    "net/http/httptest"
    "testing"

    "github.com/stretchr/testify/assert"
)

client := new(http.Client)

func TestRouter(t *testing.T) {
    router := NewRouter()
    testServer := httptest.NewServer(router)
    defer testServer.Close()

    req, _ := http.NewRequest("GET", testServer.URL+"/hello", nil)

    resp, _ := client.Do(req)
    respBody, _ := ioutil.ReadAll(resp.Body)

    assert.Equal(t, http.StatusOK, resp.StatusCode)
    assert.Equal(t, helloMessage, string(respBody))
}

httptest.ServerをHTTPSサーバとして立ち上げてテストしたいときは、httptest.NewTLSServer(router)とすることでHTTPSサーバとして立ち上げることができます。

最後に

今回はechoベースのサーバに対してテストを行いましたが、gingoji等のフレームワークでも同様にテストすることが可能です。
それでは、良いテストライフを!

97
65
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
97
65