LoginSignup
13

More than 3 years have passed since last update.

gin.Contextを引数にもつ関数をunitテストする

Last updated at Posted at 2020-07-11

はじめに

ginのmiddlewareのunitテストをしようと思ったときにちょっとハマったので備忘録としてまとめておきます

テスト内容

まずはソースツリーから

├── main.go
└── middleware
    ├── auth.go
    └── auth_test.go

シンプルにGinのクイックスタートにmiddleware.Authorizationを噛ましてるだけです

main.go
package main

import (
    "testing_gin_context/middleware"

    "github.com/gin-gonic/gin"
)

func setupRouter() *gin.Engine {
    r := gin.Default()

    // 認証用のmiddlewareを使用
    r.Use(middleware.Authorization)

    r.GET("/ping", func(c *gin.Context) {
        c.String(200, "pong")
    })
    return r
}

func main() {
    r := setupRouter()
    r.Run(":8080")
}

contextからヘッダー情報を取得し、トークンが取得できれば認証を行い、その結果をcontextに詰めて返しています。

middleware/auth.go
package middleware

import (
    "github.com/gin-gonic/gin"
)

func Authorization(c *gin.Context) {
    // リクエストヘッダーからaccessTokenを取得
    token := c.GetHeader("Authorization")
    if token == "" {
        c.AbortWithStatusJSON(http.StatusUnauthorized, JSONオブジェクト)
        return
    }

    /*
         何かしらの認証を行う・・・
    */

    // 認証の結果をcontextに詰める
    c.Set("userId", "1234567890")
    c.Set("userName", "Taro")
    c.Next()
}
middleware/auth_test.go
package middleware

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

    "github.com/gin-gonic/gin"
    "github.com/stretchr/testify/assert"
)

func TestAuthorization(t *testing.T) {
    // gin contextの生成
    ginContext, _ := gin.CreateTestContext(httptest.NewRecorder())

    // リクエストの生成
    // 今回はmiddlewareのテストのためpathはなんでも可
    req, _ := http.NewRequest("GET", "/", nil)

    // ヘッダー情報の追加
    req.Header.Add("Authorization", "AccessToken")

    // リクエスト情報をコンテキストに入れる
    ginContext.Request = req

    // Authorization関数を実行
    authMiddleware.Authorization(ginContext)


    asserts := assert.New(t)
    asserts.Equal("userId", c.GetString("1234567890"))
    asserts.Equal("userName", c.GetHeader("Taro"))
}

テストのポイント

ポイントとしては

// gin contextの生成
ginContext, _ := gin.CreateTestContext(httptest.NewRecorder())
// リクエスト情報をコンテキストに入れる
ginContext.Request = req

の2箇所あたりだと思います。

実はこのCreateTestContextどうやら以前は返り値を3つ返していたことがあるらしく、かなりいろんなところで↓のような記述を見たのですが、どうやらバージョンが変わって今の形になったっぽいです(たぶんw)
(参考文献: https://godoc.org/github.com/gin-gonic/gin#CreateTestContext

c, _, _ := gin.CreateTestContext()

またgin.Context自身は

// 公開されているフィールドのみ記述
type Context struct {
    Request   *http.Request
    Writer    ResponseWriter

    Params   Params
    handlers HandlersChain

    Errors errorMsgs

    Accepted []string
}

というように定義されていたので今回はRequestフィールドに直接リクエスト内容を入れてあげたような感じです。
(※ginの公式のテストを見てそのやり方を真似しましたw)
https://sourcegraph.com/github.com/gin-gonic/gin@8f3047814e86442c8efbd91ef7007905d47cf6c9/-/blob/context_test.go#L57

参考文献

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
13