Goのテストでプライベートの値を参照できずハマった話
Goのテストをする際にプライベートな値などを参照するためにexport_test.goといったファイルを作って、テストコードからのみ参照できるようにするテクニックがあります。
このテクニックについては次の記事がわかりやすいので知らない方はまずそちらを参照することをおすすめします。
しかし、このテクニックを使ったにも関わらずテストコード上からプライベートな値を参照できないという事態に遭遇しました。
サンプルコード
// hoge/hoge.go package hoge const fuga = 1
// hoge/export_test.go package hoge const Fuga = fuga
// hoge/hoge_test.go package hoge_test import ( "fmt" "testing" "github.com/nijinekko/blog/samples/invalidexporttest/hoge" ) func TestFuga(t *testing.T) { if hoge.Fuga != 1 { t.Error(fmt.Errorf("want 1, but got %v", hoge.Fuga)) } }
// main.go package main func main() { }
// main_test.go package main import ( "fmt" "testing" "github.com/nijinekko/blog/samples/invalidexporttest/hoge" ) func TestMain(t *testing.T) { if hoge.Fuga != 1 { t.Error(fmt.Errorf("want 1, but got %v", hoge.Fuga)) } }
これらのコードでgo test
を実行するとhoge_test.goでは、hoge.Fugaが参照できますが、main_test.goではhoge.Fugaが参照できずビルドエラーになります。
サンプルコードの全体はこちら
原因
go help test
を見てみると次のような記述があります。
'Go test' recompiles each package along with any files with names matching the file pattern "*_test.go".
Each listed package causes the execution of a separate test binary.
パッケージ毎にテストバイナリが作成されるため、mainパッケージのコンパイル時にはexport_test.goが見えないようです。