Golang + Docker + RDB ユニットテスト実行時のローカルのホスト名の問題
最近 Golang が楽しくなってきた、今回は、Golang + Docker + RDB で Golangのユニットテストで RDB 等にレコードを挿入したいときに、実行時のローカルのホスト名を読みかえなければならない問題に関して、自動化を図る方法があったので、そのメモ。
何がしたいのか
Golang の test コードから config.ReadConfig() を呼び出すことで設定の読みかえが可能になります。
Docker 等を活用している際にローカルと仮想環境内で接続先を切り替えたいときに使用します。
各種ステップ
書き換えたいファイル
db:
host: host.docker.internal #ここをlocalhostに書き換えたい
name: title
password: password
user: user
今までは手動でいちいち切り替えていたが、あまりにも効率が悪すぎるので、test を走らせる際に、自動で書き換えを行いたい。
まず、config.go
package config
import (
"io/ioutil"
"os"
err "path/to/pkg/error"
yaml "gopkg.in/yaml.v2"
)
type Config struct {
DB configDB `yaml:"db"`
}
type configDB struct {
Host string `yaml:"host"`
Name string `yaml:"name"`
Password string `yaml:"password"`
User string `yaml:"user"`
}
func ReadConfig() (*Config, error) {
file := os.Getenv("CONFIG")
if file == "" {
return nil, err.ErrorEmptyEnvironmentVariableConfig
}
buf, err := ioutil.ReadFile(file)
if err != nil {
return nil, err
}
var config Config
err = yaml.Unmarshal([]byte(buf), &config)
if err != nil {
return nil, err
}
return &config, nil
}
GolangにはYAMLの標準ライブラリがないので、
なので外部ライブラリ等を使って、
Golangの構造体やマップなどに変換(Unmarshal) と、Golangのデータ型からYAMLに変換(Marshal)できる。
ライブラリ yaml.v2
ソース: go-yaml/yaml GitHub
構造体にconfigの項目を定義し、読みかえを可能にします。
type configDB struct {
Host string `yaml:"host"`
Name string `yaml:"name"`
Password string `yaml:"password"`
User string `yaml:"user"`
}
次に例えばsetup_test.go
を書く
package db_test
import (
"path/to/pkg/config"
db "path/to/pkg/db"
"os"
"testing"
)
func TestMigration(t *testing.T) {
os.Setenv("CONFIG", "../../config.yml")
config, _ := config.ReadConfig()
config.DB.Host = "localhost" #ここで読みかえます
db.ConnectDatabase(config)
}
errorパッケージ
package error
import (
"golang.org/x/xerrors"
)
var (
ErrorEmptyEnvironmentVariableConfig = xerrors.New("Environment variable CONFIG is empty.")
)
このようにtestコードからconfig.ReadConfig()を呼び出すことで読みかえが可能になります。
Docker 等を活用している際にローカルと仮想環境内で接続先を切り替えたいときが度々発生すると思いますが、本当に便利ですね。
ありがとうございました、
もっとスマートな方法を知っているよという方がおられましたらぜひコメントください!