やったこと
・下のようなcsvファイルを読み込む処理があり、テストを実行すると、csv/sampleファイルが存在するにもかかわらず、no such file or directoryエラーとなる。
・go run コマンドで実行すると問題なく処理できる。
readCsv.go
func (b *boxerService) CreateBoxers() error {
fpath := "csv/sample.csv"
f, err := os.Open(fpath)
if err != nil {
logger.Info("Error while opening sample.csv: " + err.Error())
}
defer func() {
f.Close()
}()
~ 中略
return nil
}
パッケージ構成
┌ csv
│ └ sample.csv
└service
└ readCsv.go
エラー内容
Error while opening sample.csv: open csv/sample.csv: no such file or directory
原因
go runコマンドで実行すると、最上位のディレクトリがワーキングディレクトリとなる。
しかし、テスト実行時にはテスト対象のメソッドが存在するパッケージ(この場合serviceパッケージ)がワーキングディレクトリとなる。
serviceパッケージにはcsvファイルが存在していないため、エラーとなる。
対応案
1. ファイルパスを変更する
下記のようにファイルパスを変更すると実行可能になるが、これだとファイルパスが変わってしまい、通常実行時にエラーとなる。
なので、結局意味がない。
- fpath := "/csv/boxer.csv"
+ fpath := "../csv/boxer.csv"
2. テストデータを別に作成する
下のようにテストデータをserviceパッケージ内に作成した。
しかし、これだと名前がテスト用とわかりにくいので、あまり望ましくないと思われる。
┌ csv
│ └ sample.csv
└service
└ readCsv.go
└ csv
└ sample.csv // これはテスト用
3. メソッドのシグネチャを変更する
下のようにシグネチャを変更してファイルパスを外部から渡すようにすると、テスト時にファイルパスを渡せるので、望ましい気がする。
- func (b *boxerService) CreateBoxers() error {
+ func (b *boxerService) CreateBoxers(filepath string) error {
だが、自分の作成しているコードで外からファイルパスを渡すのはなんだか微妙な気がしたので、結局2で対応している。