Golangでファイル操作をテストする際に、tempDir() を使った便利だったのでメモしておきます。
以下のように []byteを受け取って、ファイルに書き出す関数があるとします。
import (
"os"
"path/filepath"
)
func CreateFooFile(dir string, filename string, content []byte) error {
path := filepath.Join(dir, filename)
f, err := os.Create(path)
if err != nil {
return err
}
if _, err := f.Write(content); err != nil {
return nil
}
return nil
}この関数に対するテストを記載していきます。ディレクトリ構造は以下のようにします。
├── foo.go
├── foo_test.go
└── testdata
├── bar.txt
└── foo.txttestdataフォルダには、テスト用のファイルを格納します。このファイルと上記のCreateFooFile()で出力されたファイルを比較して一致していればテスト成功です。テストコードは以下の通りです。
import (
"os"
"path/filepath"
"testing"
"github.com/google/go-cmp/cmp"
)
func TestCreateFooFile(t *testing.T) {
tests := []struct {
name string
content []byte
fn string
wantErr bool
}{
{name: "foo", content: []byte("foo"), fn: "foo.txt", wantErr: false},
{name: "bar", content: []byte("bar"), fn: "bar.txt", wantErr: false},
}
// create temp directory
dir := t.TempDir()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := CreateFooFile(dir, tt.fn, tt.content); (err != nil) != tt.wantErr {
t.Errorf("CreateSomeFile() error = %v, wantErr %v", err, tt.wantErr)
}
// get created file
got, err := os.ReadFile(filepath.Join(dir, tt.filename))
if err != nil {
t.Fatalf("handler.CreateWGServerConfig() error : %v", err)
}
// get test data
want, err := os.ReadFile(filepath.Join("testdata", tt.filename))
if err != nil {
t.Fatalf("handler.CreateClientConfig() error : %v", err)
}
if diff := cmp.Diff(string(want), string(got)); diff != "" {
t.Errorf(diff)
}
})
}
}tempDirを使って一時的なディレクトリにファイルを書き出しています。このディレクトリはこの関数のテスト終了後に削除されるため、後処理を気にする必要はありません。
出力結果の比較には、https://github.com/google/go-cmp を利用しました。差分があった場合に以下のように見やすく表示してくれます。
--- FAIL: TestCreateFooFile (0.00s)
--- FAIL: TestCreateFooFile/bar (0.00s)
/xxx/foo_test.go:43: string(
- "foo",
+ "bar",
)
FAIL