Подтвердить что ты не робот

Laravel 5.2 | Тестирование UploadedFile Пропускает значение $test после сообщения. Ошибка?

Обновление 2016/04/26 11:30 GMT + 2 Обходное решение

Так как Laravel 5.2.15, параметр $test удаляется, но нет ясной причины, потому что у Symfony UploadedFile все еще есть параметр $test.

Обходной путь заключается в том, чтобы временно использовать Laravel 5.2.14.

Обновление 2016/04/26 11:00 GMT + 2

Laravel own 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();
    }
}

Controller

namespace App\Http\Controllers;

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

        return [];
    }
}

Проблема

  • Файл для публикации имеет аргумент true для $test
  • Опубликованный файл поступает в upload()
  • $request->file('file') содержит правильные аргументы, но

    $test false

Кажется, что аргумент $test не прошел по почтовому вызову. Это ошибка?

4b9b3361

Ответ 1

Объяснение

Это действительно интересно. Вы уже много заметили при создании этого сообщения (если у кого-то проблема, следует внимательно его прочитать).

В этом commit, как вы уже упоминали, параметр $testing был удален, а код классов был упрощен, удалив Reflection, чтобы получить testing значение свойства Symfony\Component\HttpFoundation\File\UploadedFile.

И теперь сложно понять, что в зависимости от того, что вы тестируете, вы можете не заметить изменения, и все может сработать, но в некоторых случаях этого не произойдет, и вы действительно не знаете, почему.

Например, все может работать - файл будет загружен без проблем, но если вы добавите в свой класс Request пример mimes, например:

'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, но теперь он будет использоваться позже без проблем)