例えば、LaravelでCSVファイルをアップロードしてその中身の値をつかって何かのレスポンスを返す。
みたいな処理のときのHTTPテスト。
テスト用で任意のダミーCSVをアップロードしたい。
そのときに、CSVの中身もテストコードに含めたい。
こんな感じでやってみました。
UploadCsvTest.php
///・・・・・
/**
* CSVアップロードテスト
* アップロードされたCSVを処理するコントローラなどのテスト
*
* @return void
*/
public function testCsvUpload()
{
// 一時ファイルを作成
$tmp_fp = tmpfile();
// CSVファイルとして書き込む
$csv_rows = [
[
'なまえ1',
'住所1',
'電話番号1',
],
[
'なまえ2',
'住所2',
'電話番号2',
]
];
foreach ($csv_rows as $csv_row) {
fputcsv($tmp_fp, $csv_row);
}
// 一時ファイルのパスを取得
$tmp_meta = stream_get_meta_data($tmp_fp);
$tmp_path = $tmp_meta["uri"];
// 一時ファイルからアップロードファイルを作成
$file = new UploadedFile($tmp_path, 'upload.csv', 'text/plain', filesize($tmp_path), null, true);
// POSTリクエスト送信してレスポンス取得
$response = $this->json('POST', '/upload', [
'csv_file' => $file,
]);
// 何かしら検証する
// $response->assertStatus(200);
}
- わかりやすくテストメソッド内で書いたけど、ほんとは
setUp()
内とかで一時CSVファイルをつくれば各メソッドで使い回せる。 - 一時ファイルの削除はスクリプト終了時に自動的にされるらしいけど、明示的に書いたほうがいいのかな?
- 大きなCSVを使いたいときはコードに書くと長くなるので、別にテスト用ファイルを用意して以下のようにすればよい。
// strage/test/data/dumy.csv からアップロードファイルを作成
$file = new UploadedFile(storage_path('test/data/dumy.csv'), 'upload.csv', 'text/plain', null, null, true);
※第4引数はファイルサイズですが、nullでも動くみたい?