7
8

More than 5 years have passed since last update.

EchoでSessionを利用したテストを行う

Posted at

セッション機能の導入はこちらを参考に
https://qiita.com/to-hutohu/items/740ee30aa996c0bd8d7e

環境

  • Go1.9
  • echo 3.2.3
  • srinathgs/mysqlstore

流れ

  1. テストを行う前にセッションストアにデータを入れておく
  2. ミドルウェアを通してハンドラを返す
  3. 後は通常通り

example.go
func Handler(c echo.Context) error {
    sess, err := session.Get("sessions", c)
    if err != nil {
        return fmt.Errorf("Failed to get session: %v", err)
    }

    var userId string
    if sess.Values["userId"] != nil {
        userId = sess.Values["userId"].(string)
    }
    // 処理
}

テストコード(抜粋)

example_test.go
func beforeTest(t *testing.T) (*echo.Echo, *http.Cookie, echo.MiddlewareFunc) {
    e := echo.New()

    store, err := mysqlstore.NewMySQLStore(endpoint, 
                    "sessions", "/", 60*60*24*14, []byte("secret"))

    if err != nil {
        t.Fatal(err)
    }

    // セッション情報をあらかじめストアに保存しておく
    req := httptest.NewRequest(echo.GET, "/", nil)
    rec := httptest.NewRecorder()
    sess, err := store.New(req, "session")
    sess.Values["userId"] = "testUser"

    err = sess.Save(req, rec)
    if err != nil {
        t.Fatal(err)
    }

    // セッションIDを取得して使いまわせるようにしておく
    cookie := parseCookies(rec.Header().Get("Set-Cookie"))["session"]
    mw := session.Middleware(store)

    return e, cookie, mw
}

func TestGetChannelsHandler(t *testing.T) {
    e, cookie, mw := beforeTest(t)

    // ミドルウェアを通してハンドラの設定
    rec := request(e, t, mw(Handler), cookie)
    // レスポンスのチェック
}


func request(e *echo.Echo, t *testing.T, handler echo.HandlerFunc, cookie *http.Cookie) *httptest.ResponseRecorder {
    req := httptest.NewRequest("GET", "http://test", nil)

    req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)

    // クッキーに設定しておく
    if cookie != nil {
        req.Header.Add("Cookie", fmt.Sprintf("%s=%s", cookie.Name, cookie.Value))
    }
    rec := httptest.NewRecorder()
    c := e.NewContext(req, rec)
    err := handler(c)

    if err != nil {
        t.Fatal(err)
    }

    return rec
}

func parseCookies(value string) map[string]*http.Cookie {
    m := map[string]*http.Cookie{}
    for _, c := range (&http.Request{Header: http.Header{"Cookie": {value}}}).Cookies() {
        m[c.Name] = c
    }
    return m
}

複数のエンドポイントをテストする場合には上のようにリクエスト部分をある程度まとめておくと、コードが簡潔になりそうです。

7
8
0

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
7
8