Update 2016/04/26 11:30 GMT+2 Workaround
Since Laravel 5.2.15, the $test parameter is removed, but there is no clear reason, because Symfony's UploadedFile still has the $test parameter.
A workaround is to use Laravel 5.2.14 provisionally.
Update 2016/04/26 11:00 GMT+2
Laravel's own UploadedFile doesn't pass the $test parameter. See these resources:
- https://github.com/laravel/framework/issues/12620
- https://github.com/laravel/framework/commit/5062a9b42632e55ee90b7397141c0b12622447e1
I know, there's another question: How to test file upload in Laravel 5.2, but the marked answer doesn't work for me.
Test Case
I create an instance of Symfony's UploadedFile class and I set $test
to true
. I post the file to 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 [];
}
}
Problem
- The file to post has the argument
true
for$test
- The posted file arrives in
upload()
$request->file('file')
contains the right arguments, but$test is false
It seems the argument $test is not past by the post call. Is this a bug?
Explanation
This is really interesting thing. You've noticed already a lot of when creating this post (if anyone has the problem should read it carefully).
In this commit as you already mentioned
$testing
parameter was removed and code of classes was simplified removing Reflection to gettesting
property value ofSymfony\Component\HttpFoundation\File\UploadedFile
.And now the tricky thing is that depending on what you are testing, you might event not notice the change and everything might work but in some cases it won't and you won't really know why.
For example everything might work - file will be uploaded without a problem, but if you add into your Request class for instance
mimes
rule like so:it will fail telling you the file has invalid mime (this is because internally it will be also verified if file was really uploaded and in case of tests in fact it's not the same as real upload).
The solution is looking again at what was really changed into the commit and how the method look like. In this file instance of uploaded file is returned like so:
so in case if the file is instance of this class it will return this instance unmodified, otherwise it will create now object without passing
$testing
argument to class constructor.Solution
So to solve this, when testing file uploads you should not use
class anymore. You should now use
to don't get any strange issues when testing file uploads (of course you should still pass to this object constructor
true
as$testing
parameter but now it will be used later without a problem)