web-dev-qa-db-ja.com

Laravel 5.2 | UploadedFileをテストすると、投稿後に$ test値が失われます。バグ?

更新2016/04/2611:30 GMT +2回避策

Laravel 5.2.15なので、$ testパラメーターは削除されますが、SymfonyのUploadedFileにはまだ$ testパラメーターがあるため、明確な理由はありません。

回避策は、Laravel 5.2.14を暫定的に使用することです。

更新2016/04/2611:00 GMT + 2

Laravel自身のUploadedFileは$ testパラメーターを渡しません。次のリソースを参照してください。

私は知っています、別の質問があります: ファイルのアップロードをLaravel 5.2 でテストする方法ですが、マークされた答えは私には機能しません。

テストケース

SymfonyのUploadedFileクラスのインスタンスを作成し、_$test_をtrueに設定します。ファイルを_file/upload_に投稿します。

_class FileControllerTest extends TestCase
{
    use \Illuminate\Foundation\Testing\DatabaseTransactions;

    private $file;

    public function setUp()
    {
        parent::setUp();

        $this->file = new Symfony\Component\HttpFoundation\File\UploadedFile(
            public_path() . '/examples/example.jpg',
            'example.jpg',
            'image/jpeg',
            filesize(public_path() . '/examples/example.jpg'),
            null,
            true // for $test
        );
    }

    /** @test */
    public function it_uploads_a_valid_file()
    {
        var_dump($this->file); // $test = true
        $this->call('POST', 'file/upload', [], [], ['file' => $this->file],
            ['accept' => 'application/json']);

        $this->assertResponseOk();
    }
}
_

コントローラ

_namespace App\Http\Controllers;

class FileController extends Controller
{
    public function upload(Request $request)
    {
        var_dump($request->file('file')); // $test = false

        return [];
    }
}
_

問題

  • 投稿するファイルには、_$test_の引数trueがあります
  • 投稿されたファイルはupload()に到着します
  • $request->file('file')には正しい引数が含まれていますが、

    $ testfalse

引数$ testはポストコールまでに過ぎていないようです。これはバグですか?

22
schellingerht

説明

これは本当に面白いことです。この投稿を作成するときに、すでに多くのことに気づいています(問題がある場合は、注意深く読んでください)。

この中で commit すでに述べたように、$testingパラメータが削除され、クラスのコードが簡略化されてReflectionが削除され、Symfony\Component\HttpFoundation\File\UploadedFiletestingプロパティ値が取得されました。

そして今、トリッキーなことは、テストしているものによっては、変更に気付かず、すべてが機能する可能性があることですが、場合によっては機能せず、理由がわからないこともあります。

たとえば、すべてが機能する可能性があります。ファイルは問題なくアップロードされますが、たとえばmimesルールをRequestクラスに追加すると、次のようになります。

'logo' => ['mimes:jpeg,png'],

ファイルに無効なmimeがあることを通知するのに失敗します(これは、ファイルが実際にアップロードされたかどうかも内部的に検証され、テストの場合は実際のアップロードと同じではないためです)。

解決策は、コミットに実際に変更されたものと、メソッドがどのように見えるかをもう一度確認することです。 このファイル アップロードされたファイルのインスタンスは次のように返されます:

 return $file instanceof static ? $file : new static(
            $file->getRealPath(), $file->getClientOriginalName(), $file->getClientMimeType(),
            $file->getClientSize(), $file->getError()
        );

したがって、ファイルがこのクラスのインスタンスである場合は、このインスタンスを変更せずに返します。それ以外の場合は、クラスコンストラクタに$testing引数を渡さずにオブジェクトを作成します。

解決

したがって、これを解決するには、ファイルのアップロードをテストするときにを使用しないでください

\Symfony\Component\HttpFoundation\File\UploadedFile

もうクラス。今使用する必要があります

\Illuminate\Http\UploadedFile

ファイルのアップロードをテストするときに奇妙な問題が発生しないようにします(もちろん、このオブジェクトコンストラクターtrue$testingパラメーターとして渡す必要がありますが、後で問題なく使用されます)

31