【Go】Goのテストに入門してみた! ~httptest編①~
はじめに
前回は「Fuzzingテスト」を見ていきました。
今回は「httptest」に入門します。
前回の記事はこちら!
この記事でわかること
- Goの標準パッケージである
httptestの概要や役割 -
httptestを使ったHTTPハンドラーのテスト方法
httptestとは?
httptest はGoに標準搭載されているパッケージです。
(net/http/httptest が該当します。)
httptest を使うことで、実際にHTTPサーバーを立ち上げることなく、HTTPハンドラーやWebアプリケーションのテストを簡単に行うことができます。
GoのhttptestでGETリクエストをテストする方法
今回はGETメソッドで httptest を使ったハンドラーのテストをしてみます。
フレームワークはEchoを使います。
package main
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/labstack/echo/v4"
)
func helloHandler(c echo.Context) error {
return c.String(http.StatusOK, "Hello, Echo!")
}
func TestHelloHandler(t *testing.T) {
e := echo.New()
req := httptest.NewRequest(http.MethodGet, "/hello", nil)
rec := httptest.NewRecorder()
c := e.NewContext(req, rec)
if err := helloHandler(c); err != nil {
t.Fatalf("handler returned error: %v", err)
}
if rec.Code != http.StatusOK {
t.Errorf("expected status 200, got %d", rec.Code)
}
if rec.Body.String() != "Hello, Echo!" {
t.Errorf("expected body %q, got %q", "Hello, Echo!", rec.Body.String())
}
}
実行すると、以下のような結果が得られます。
# go test -v
=== RUN TestHelloHandler
--- PASS: TestHelloHandler (0.00s)
PASS
ok go-test-practice 0.384s
httptest + Echoハンドラーの実装解説
1. ハンドラーの定義
func helloHandler(c echo.Context) error {
return c.String(http.StatusOK, "Hello, Echo!")
}
今回は「Hello, Echo!」を出力するシンプルな実装です。
2. Echoインスタンスの作成
e := echo.New()
Echoのルーティングやハンドラーをテストするために必要なインスタンスを作成します。
3. テスト用のリクエストとレスポンスを作成
req := httptest.NewRequest(http.MethodGet, "/hello", nil)
rec := httptest.NewRecorder()
それぞれ以下の役割を果たしています。
-
httptest.NewRequest():擬似リクエストを作成- 第一引数:実施したいHTTPリクエストメソッド
- 第二引数:実施したいエンドポイント
- 第三引数:リクエストボディ(今回はGETメソッドなのでnil)
-
httptest.NewRecorder():ハンドラーの出力を書き込むための擬似レスポンスライター
4. Echoコンテキストの作成
c := e.NewContext(req, rec)
Echo独自のコンテキストを作成します。
コンテキストにリクエストとレスポンスの疑似オブジェクトを入れることで、実際のリクエストと同様にハンドラーを実行できます。
5. ハンドラーを実行
if err := helloHandler(c); err != nil {
t.Fatalf("handler returned error: %v", err)
}
ハンドラーにコンテキストを渡し、ハンドラーを実行します。
もしエラーが返された場合はテストを失敗させます。
6. レスポンスのステータスコードを確認
if rec.Code != http.StatusOK {
t.Errorf("expected status 200, got %d", rec.Code)
}
期待するステータスコードとレスポンスのコードが一致するかをチェックします。
一致しない場合はエラーを返します。
7. レスポンスの本文を確認
if rec.Body.String() != "Hello, Echo!" {
t.Errorf("expected body %q, got %q", "Hello, Echo!", rec.Body.String())
}
期待する本文とレスポンスの本文が一致するかをチェックします。
一致しない場合はエラーを返します。
まとめ
今回は「httptest」について学びました。
Goの httptest パッケージを使えば、実際にサーバーを立ち上げなくてもHTTPハンドラーの挙動をテストすることができます。
擬似リクエストとレスポンスを作成し、コンテキストに渡すことで、ハンドラーのステータスコードやレスポンス本文を簡単に検証することができます。
この手法を使えば、サーバー起動不要で効率的にハンドラーの動作確認ができ、堅牢なWebアプリケーション開発に役立つということがわかりました。
次回も「httptest」に入門します!
参考
Discussion