kodama-tech.blog

技術的なこといろんなこと書きます。golangに関すること多めです。

goでHTTPをmock化するお話。

こんにちは、こだまです。

今回はユニットテストのお話をしようかなと。

みなさん、ユニットテストを書くときに「あー、mock化しなきゃー」って思うことよくありますよね。
例えばjavaなんかはJMockitなんていう非常に優秀すぎるくらいのライブラリがあるのですが、新進気鋭のgolangにもそんなものないのかなと調べていたら見つかりました。

今回紹介するのは、httpmockというライブラリです。
名前からどんなことができるのかわかりますね。

mock化したいHTTP通信を指定するだけで、期待する結果を返してくれるというなんとまあ優秀なライブラリです。
ちなみに、READMEに書いてありますが、go1.5以下には適用していませんので、ご注意を。

使い方は非常に簡単。
公式の使用例を細かく解説していきます。

func TestFetchArticles(t *testing.T) {
    // httpmockの有効化
    httpmock.Activate()
    // 処理後にリセットを行う
    defer httpmock.DeactivateAndReset()

    user := make([]map[string]string)

    // mock化したいRequestを登録
    // (requestするhttpメソッド名, requestするURL, 期待する戻り値)を引数に設定する
    httpmock.RegisterResponder("GET", “http://path/to/request“,
        func(req *http.Request) (*http.Response, error) {
            res, err := httpmock.NewJsonResponse(200, user)
            if err != nil {
                return httpmock.NewStringResponse(500, ""), nil
            }
            return res, nil
        },
    )
}

ここで、使用している2つの関数をよく使用すると思います。
まず、一つめ。
httpmock.NewJsonResponse(200, user)
第一引数にHTTPのステータスコードを、第二引数にはmapを指定します。
golangを使用しているとmapよりよく使うであろうstructも指定可能です。
その際は、必ずjsonアノテーションをつけておきましょう。

二つめ。
httpmock.NewStringResponse(500, “”)
こちらの第二引数には文字列を指定します。例では空文字を送っているのですが、
何かしらの値を返却した場合は、以下のようにJSON形式で返却しておくと使い勝手が良いと思います。

httpmock.NewStringResponse(500, `{“err”:”InternalServerError”}`)

テストはまだまだライブラリが充実していないので、非常にやりづらいですね。。。
(ただでさえテストを書くのが嫌いなのに)