🗳

【Laravel】APIテストで自分で用意したテスト用ファイルをアップロードする。

2021/09/19に公開

背景

Laravelでファイルアップロードをテストする際にはUploadedFile::fake()でダミーデータを送信することができる。[1]

    public function test_import_success()
    {
        Excel::fake();
        Storage::fake();

        $response = $this->post(route('users.excel.import.upload'), [
            'users' => UploadedFile::fake()->create(
                name: 'users.xlsx',
                mimeType: 'application/vnd.openxmlformats-officedocument.spread'
            )
        ]);

        $response->assertOk();
    }

しかし、CSVやエクセルからレコードをインポートするAPIのテスト時には、自分で用意したテストデータを持つファイルをアップロードしたい。

検索したが日本語ではヒットしなかったのでメモ。[2]

実装

Illuminate\Http\UploadedFileをテストコード中でnewしてあげれば良い。

    public function test_import_success()
    {
        $response = $this->post(route('users.excel.import.upload'), [
            'users' => new UploadedFile(
                './tests/Feature/data/import_success.xlsx',
                'import_success.xlsx',
                'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
                null,
                true
            )
        ]);

        $response->assertOk();
    }

コンストラクタの引数はIlluminate\Http\UploadedFileの継承元であるSymfony\Component\HttpFoundation\File\UploadedFileソースを参照すると説明が書いてある。

Symfony\Component\HttpFoundation\File\UploadedFile.php(抜粋)
     * @param string      $path         The full temporary path to the file
     * @param string      $originalName The original file name of the uploaded file
     * @param string|null $mimeType     The type of the file as provided by PHP; null defaults to application/octet-stream
     * @param int|null    $error        The error constant of the upload (one of PHP's UPLOAD_ERR_XXX constants); null defaults to UPLOAD_ERR_OK
     * @param bool        $test         Whether the test mode is active
     *                                  Local files are used in test mode hence the code should not enforce HTTP uploads

注意するべき点は2つ

  • アップロード失敗状態を再現したい場合は$errorUPLOAD_ERR_NO_FILE等のPHP定義済み定数を定義してあげる。
  • テスト時に$testtrueにする。 ※試しにfalseにするとファイルがAPIに渡されない模様

結言

テストを書くことを簡単にあきらめないで
※記事へのご指摘歓迎いたします。

脚注
  1. https://laravel.com/docs/8.x/http-tests#testing-file-uploads ↩︎

  2. 英語ではstackoverflowの記事が存在する。 ↩︎

GitHubで編集を提案

Discussion