LoginSignup
10
5

More than 5 years have passed since last update.

Goのテストの初期化処理でハマったところ

Last updated at Posted at 2017-03-07

MySQLやRabbitMQ、Redisなどに接続する処理があるサービスのテストを書こうとしたらハマった。
golang1.4から

func TestMain(m *testing.M)

という関数が定義されていればこれがまず実行されて、ここに初期化処理や終了時の処理を書けば良いということだったので、mainパッケージにmain_test.goのようなファイルを作り、envファイルのロードや、DBの接続を行う処理を書いた。
(参考:http://golang-jp.org/pkg/testing/ )

main_test.go
package main

import (
"testing"
"github.com/my_account/my_worker/cmd"
"github.com/my_account/my_worker/models"
"os"
)

//Check variables @ config/env/test.env
func TestMain(m *testing.M) {
    before()
    code := m.Run()
    after()
    os.Exit(code)
}

func before(){
cmd.InitConfig() //環境変数のロード
models.InitDBConnection() //DB接続処理
}

func after(){
}

初期化処理ができたので、テスト書いていくかーと思い
models/aaa_test.goみたいなファイルを作り、テストを書いてみたが、どうもDBの接続に失敗しているらしく読み込んだはずの環境変数も取得できない。

aaa_test.go

package models

import (
    "github.com/stretchr/testify/assert"
    "testing"
)

func TestIsWhiteListed(t *testing.T) {

  b := IsWhiteListed(123456, 34)
  assert.Equal(t, b, true, "they should be equal")

}

そもそもmain_test.goでの初期化処理が失敗してるのでは?と思いmain_test.goのbefore()関数の後で環境変数やパッケージのグローバル変数をチェックすると正しく処理できていた。
その後小一時間ほど悩んで試行錯誤している時に

m.Run()

を消してテストを実行したところ、models/aaa_test.goのテストが走ったので、これはもしかして・・と思い
models/init_test.goみたいなファイルを作り、ここにも

func TestMain(m *testing.M)

を定義して、初期化処理を行ったら予想通りの動きをしくれた。
どうやら初期化処理を行いたい場合は、パッケージ毎に

func TestMain(m *testing.M)

が必要らしい。
あと、環境変数のロードはgodotenv( https://github.com/joho/godotenv )を使っていたんだけど、どうやらテストが実行されるパッケージごとにカレントディレクトリが変わるらしく、repositoryのルートに.envを置いている場合は

  godotenv.Load("../.env")

のようにしてロードしないとダメみたいです。

10
5
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
10
5