Laravel 5.2 |测试 UploadedFile 在 Post 之后缺少 $test 值。漏洞?

Laravel 5.2 | Testing UploadedFile Misses the $test Value after Post. Bug?

更新 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 自己的 UploadedFile 没有传递 $test 参数。查看这些资源:

我知道,还有一个问题:,但标记的答案对我不起作用。

测试用例

我创建了一个 Symfony 的 UploadedFile class 实例,并将 $test 设置为 true。我post文件到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 没有被 post 调用过去。这是一个错误吗?

说明

这真是一件有趣的事情。您在创建此 post 时已经注意到了很多(如果有人遇到问题,请仔细阅读)。

在这个 commit 中,正如您已经提到的,$testing 参数被删除,classes 的代码被简化,删除了反射以获得 testing 属性 值共 Symfony\Component\HttpFoundation\File\UploadedFile.

现在棘手的事情是,根据您正在测试的内容,您可能不会注意到更改并且一切都可能有效,但在某些情况下它不会并且您不会真正知道为什么。

例如,一切都可能有效 - 文件将毫无问题地上传,但是如果您将 class 添加到您的请求中,例如 mimes 规则如下:

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

它不会告诉你文件有无效的 mime(这是因为在内部它也会验证文件是否真的上传了,如果测试实际上它与真正的上传不一样)。

解决方案是再次查看真正更改为提交的内容以及该方法的外观。在 this file 中,上传文件的实例是 returned 像这样:

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

所以如果文件是这个 class 的实例,它将 return 这个实例不被修改,否则它会创建 now 对象而不将 $testing 参数传递给 class构造函数。

解决方案

所以要解决这个问题,当测试文件上传时你不应该使用

\Symfony\Component\HttpFoundation\File\UploadedFile

class 了。您现在应该使用

\Illuminate\Http\UploadedFile

在测试文件上传时不要出现任何奇怪的问题(当然你仍然应该传递给这个对象构造函数true作为$testing参数但是现在以后使用它不会有问题)