💨

Golang + Docker + RDB ユニットテスト実行時のローカルのホスト名の問題

2021/05/27に公開

Golang + Docker + RDB ユニットテスト実行時のローカルのホスト名の問題

最近 Golang が楽しくなってきた、今回は、Golang + Docker + RDB で Golangのユニットテストで RDB 等にレコードを挿入したいときに、実行時のローカルのホスト名を読みかえなければならない問題に関して、自動化を図る方法があったので、そのメモ。

何がしたいのか

Golang の test コードから config.ReadConfig() を呼び出すことで設定の読みかえが可能になります。
Docker 等を活用している際にローカルと仮想環境内で接続先を切り替えたいときに使用します。

各種ステップ

書き換えたいファイル

config.yml
db:
  host: host.docker.internal #ここをlocalhostに書き換えたい
  name: title
  password: password
  user: user

今までは手動でいちいち切り替えていたが、あまりにも効率が悪すぎるので、test を走らせる際に、自動で書き換えを行いたい。

まず、config.go

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パッケージ

error.go
package error

import (
	"golang.org/x/xerrors"
)

var (
	ErrorEmptyEnvironmentVariableConfig = xerrors.New("Environment variable CONFIG is empty.")
)

このようにtestコードからconfig.ReadConfig()を呼び出すことで読みかえが可能になります。

Docker 等を活用している際にローカルと仮想環境内で接続先を切り替えたいときが度々発生すると思いますが、本当に便利ですね。

ありがとうございました、
もっとスマートな方法を知っているよという方がおられましたらぜひコメントください!

GitHubで編集を提案

Discussion