Go学習日誌 #2022/06/21

テスト作成

実施事項

昨日は吐き気凄くてサボりました。
実施事項は下記
・環境変数を実行環境とテスト環境で分離
・Userモデルテストを作成

環境変数の分離

DBへの接続関数を以下のように書いていたが、テストする際は.envファイルで接続先のDBを変更する様にしたかった。
Railsでは開発用DBとテスト用DBが切り分けられていたので。。。

func DataBaseConnect() *gorm.DB {
	env := godotenv.Load() // Load env file
...
	return db
}

開発用はすでにコードを書いてしまっているので変更を加えたくないのでオプションを使って、テスト時のみ.envファイルの読み込み先を変更する実装とした。
オプションの実装は下記の最後の方式を参考にして、

以下のようにした。

// pathオプション構造体
type PathOptions struct {
	path string
}

type option func(*PathOptions)

// pathオプションを設定する関数
func SetPathOption(path string) option {
	return func(po *PathOptions) {
		po.path = path
	}
}

func DataBaseConnect(opts ...option) *gorm.DB {
	// デフォルトパラメータを定義
	g := &PathOptions{
		path: ".env",
	}
	// ユーザから渡された値だけ上書き
	for _, opt := range opts {
		opt(g)
	}

	env := godotenv.Load(g.path) // Load env file
...
	return db
}

Userモデルテストを作成

RSpec風にとりあえず書いてみた。

var _ = Describe("Models", func() {
	Describe("User", func() {
		th := test.TestHelper{}
		BeforeEach(func() {
			th.SetupTest()
		})
		AfterEach(func() {
			th.TearDownTest()
		})
		Context("Userが正しい時", func() {
			aud := time.Now().String()
			user := models.User{
				Aud:  &aud,
				Name: time.Now().String(),
			}
			It("Userが作成される", func() {
				err := th.DB.Create(&user).Error
				Expect(err).Should(BeNil())
			})
		})
		Context("Audがない時", func() {
			erruser := models.User{
				Name: time.Now().String(),
			}
			It("Userが作成されない", func() {
				err := th.DB.Create(&erruser).Error
				Expect(err).ShouldNot(BeNil())
			})
		})
	})
})

Userモデルは以下のようになっている。

type User struct {
	ID        uuid.UUID      `json:"id" gorm:"primaryKey;type:uuid;default:uuid_generate_v4()"`
	Aud       string          `json:"-" gorm:"index;unique;not null"`
	Name      string         `json:"name"`
	Lifelogs  []LifeLog      `json:"lifelog"`
	CreatedAt time.Time      `json:"-"`
	UpdatedAt time.Time      `json:"-"`
	DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
}

ところが、テスト実行で問題発生。

------------------------------
• [FAILED] [0.045 seconds]
Models
  User
    Audがない時
      [It] Userが作成されない

  Expected
      <nil>: nil
  not to be nil

テストでAud設定してないから当然AudがNULLでDBに書き込まれると思っていたが、実際は空文字で書き込まれていた。(string型のデフォルト値は空文字らしい)
なので、モデルのAudをポインタに変更。

type User struct {
	ID        uuid.UUID      `json:"id" gorm:"primaryKey;type:uuid;default:uuid_generate_v4()"`
	Aud       *string         `json:"-" gorm:"index;unique;not null"`
	Name      string         `json:"name"`
	Lifelogs  []LifeLog      `json:"lifelog"`
	CreatedAt time.Time      `json:"-"`
	UpdatedAt time.Time      `json:"-"`
	DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
}

これでバリデーションチェックでNULL検知ができるようになり、テストが通るようになった。

この記事が気に入ったらサポートをしてみませんか?