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 参数。查看这些资源:
- https://github.com/laravel/framework/issues/12620
- https://github.com/laravel/framework/commit/5062a9b42632e55ee90b7397141c0b12622447e1
我知道,还有一个问题:,但标记的答案对我不起作用。
测试用例
我创建了一个 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 [];
}
}
问题
- post 的文件具有
true
用于 $test
的参数
- posted 文件到达
upload()
$request->file('file')
包含正确的参数,但是
$test 是 false
似乎参数 $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
参数但是现在以后使用它不会有问题)
更新 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
我知道,还有一个问题:
测试用例
我创建了一个 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 [];
}
}
问题
- post 的文件具有
true
用于$test
的参数
- posted 文件到达
upload()
$request->file('file')
包含正确的参数,但是$test 是 false
似乎参数 $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
参数但是现在以后使用它不会有问题)