goで関数変数定数のパッチとモック

最近はGoでのテスト時の値の置き換えのしかたとかすごい悩んでます
最近自分がやった策をメモしておく。ただの所感ポエム。

関数のパッチ

MonkeyPatch最強。悩む必要なし
github.com

  • テストしたい関数
func Hoge(a string, b int) (string, error) {
    return "hoge", nil
}
  • テスト
func TestHoge(t *testing.T) {
    monkey.Patch(Hoge, func(string, int) (string, error) { return "fuga", nil})
    ~~テスト~~
}

ちなみに monkey.Patch() 先生は関数しかパッチできないので無理をしようとすると怒られる。

panic: target has to be a Func [recovered]
    panic: target has to be a Func

定数・変数のパッチ

自分が調べた限り、パッチするようなライブラリはない(あったら教えてください)。
メッチャ苦労するので、設計段階から置き換えやすいIFにしておくのが得策の様子。

苦心した方法は下記。

  1. envに入れる
    os.GetEnv("HOGEHOGE") に格納しておいて、都度そこから引っ張り出す。環境ごとに変更。
    テスト時は os.SetEnv("HOGEHOGE") でどうにかなる
  2. configファイルを用意、上書き
    コンフィグファイルに定数にしたいものを定義しておく。ただし var で。
    テスト時はそこを書き換える。けっこう無理矢理である。

コンフィグファイル

package config

var (
    Hoge = "foobar"
)

テスト

config.Hoge = "piyofuga"

モック

モックをするには interface が必要らしいので、ちょっと関数だけ…なときにはモックを作るほうにめんどうくささが偏っていく。
とりあえず interface があるなら(もしくはこのために作っても良いのなら) mockry とか gomock とか選択肢はある。
ジェネレートするだけ簡単仕様、使い方は色んな人が書いているからどうにかなる。

github.com

github.com


感想、設計がちゃんとしてればテストもラクなんだろうなあって思った(こなみかん)。
テストのしやすさも考えて実装しないと「テストどうやるの…」になって詰む。
Goはその辺試される言語ですね。ザコーダーにはつらい。