Laravel 5.2 |测试 UploadedFile 在发布后错过了 $test 值。漏洞?

Posted

技术标签:

【中文标题】Laravel 5.2 |测试 UploadedFile 在发布后错过了 $test 值。漏洞?【英文标题】:Laravel 5.2 | Testing UploadedFile Misses the $test Value after Post. Bug? 【发布时间】:2016-08-19 20:39:48 【问题描述】:

更新 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 参数。查看这些资源:

https://github.com/laravel/framework/issues/12620 https://github.com/laravel/framework/commit/5062a9b42632e55ee90b7397141c0b12622447e1

我知道,还有一个问题:How to test file upload in 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 [];
    

问题

要发布的文件有 true 的参数 $test 发布的文件到达upload()

$request->file('file') 包含正确的参数,但是

$testfalse

似乎参数 $test 没有被 post 调用过去。这是一个错误吗?

【问题讨论】:

【参考方案1】:

说明

这真的很有趣。您在创建这篇文章时已经注意到了很多(如果有人有问题,请仔细阅读)。

在这个commit 中,正如你已经提到的,$testing 参数被删除,类的代码被简化,删除反射以获取Symfony\Component\HttpFoundation\File\UploadedFiletesting 属性值。

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

例如,一切都可能正常工作 - 文件将毫无问题地上传,但如果您添加到您的请求类中,例如 mimes 规则,如下所示:

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

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

解决方案是再次查看提交中真正更改的内容以及方法的外观。在this file 上传文件的实例返回如下:

 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参数传递给这个对象构造函数,但现在它会在以后使用没有问题)

【讨论】:

@schellingerht 没问题,我今天遇到了同样的问题,正试图弄清楚发生了什么 Laravel 是我一直在研究的一个很棒的框架,但是这些重大变化让我很生气!我花了很多时间才弄清楚,在升级到 5.2.29 后,v5.2.0 运行良好,这个错误也发生在我身上,通过使用 \Illuminate\Http\UploadedFile 解决了。 @MarcinNabiałek 你在构造函数中有错误的 mimeType 和 size 变量。 @AndrewMcLagan 你为什么这么认为?构造函数的签名是 __construct($path, $originalName, $mimeType = null, $size = null, $error = null, $test = false) 所以第一个是 mime 然后是大小 谢谢。他们应该在升级指南中加入这一重大变化。

以上是关于Laravel 5.2 |测试 UploadedFile 在发布后错过了 $test 值。漏洞?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.2:测试上传的文件是不是有效:非对象上的 isValid()

Laravel 5.2 |测试 UploadedFile 在发布后错过了 $test 值。漏洞?

Laravel 5.2 单元测试错误:BadMethodCallException:调用未定义的方法 Illuminate\Database\Query\Builder::make()

硒和 Laravel 5.2

Laravel 5.2 PHPUnit JSON Api 请求正文未设置

在laravel 5.2中使用工厂关系违反完整性约束