あいつの日誌β

働きながら旅しています。

gin 入門(2)

前回は DB Layer のテストケースを考えました。 今回は WEB Layer のテストケースを考えます。

web layer のテストケースを考える

巷の記事を読んでもイマイチ書き方が分からないので実際に gin のテストコードを参考にして web layer のテストケースを考えます。

create server/main_test.go:

package main

import (
    "github.com/gin-gonic/gin"
    "github.com/stretchr/testify/assert"
    "io/ioutil"
    "net/http"
    "testing"
    "time"
)

func testRequest(t *testing.T, url string) {
    resp, err := http.Get(url)
    defer resp.Body.Close()
    assert.NoError(t, err)

    body, ioerr := ioutil.ReadAll(resp.Body)
    assert.NoError(t, ioerr)
    assert.Equal(t, "pong", string(body), "resp body should match")
    assert.Equal(t, "200 OK", resp.Status, "should get a 200")
}

func TestRun(t *testing.T) {
    router := gin.New()
    router.GET("/ping", func(c *gin.Context) {
        c.String(200, "pong")
    })
    go func() {
        assert.NoError(t, router.Run())
    }()
    // have to wait for the goroutine to start and run the server
    // otherwise the main thread will complete
    time.Sleep(5 * time.Millisecond)

    assert.Error(t, router.Run(":8080"), "already running")
    testRequest(t, "http://localhost:8080/ping")
}

テスト実行

% go test server/main_test.go
ok      command-line-arguments  0.022s

ちなみにこのテストケースは以下を参考にしました。 https://github.com/gin-gonic/gin/blob/master/gin_integration_test.go

main から router を切り出す

create server/router.go:

package main

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

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

create server/router_test.go:

package main

import (
    "github.com/gin-gonic/gin"
    "github.com/stretchr/testify/assert"
    "io/ioutil"
    "net/http"
    "testing"
    "time"
)

func testRequest(t *testing.T, url string) {
    resp, err := http.Get(url)
    defer resp.Body.Close()
    assert.NoError(t, err)

    body, ioerr := ioutil.ReadAll(resp.Body)
    assert.NoError(t, ioerr)
    assert.Equal(t, "pong", string(body), "resp body should match")
    assert.Equal(t, "200 OK", resp.Status, "should get a 200")
}

func TestRun(t *testing.T) {
    router := gin.New()
    AddRoute(router)
    go func() {
        assert.NoError(t, router.Run())
    }()
    // have to wait for the goroutine to start and run the server
    // otherwise the main thread will complete
    time.Sleep(5 * time.Millisecond)

    assert.Error(t, router.Run(":8080"), "already running")
    testRequest(t, "http://localhost:8080/ping")
}

冒頭に作成した server/main_test.go は不要になったので削除

% rm server/main_test.go

テスト実行

% go test server/*
ok      command-line-arguments  0.020s

ひとまずこれで WEB API のテストができるようになりました。 次回は CLI について考えます。