You've not told us very much about what you've done, so it's difficult to respond with specifics. However, this may help you in the right direction:
$uploadedFile = new Symfony\Component\HttpFoundation\File\UploadedFile('/path/to/file', 'original-file-name.ext');
$response = $this->call('POST', 'upload', [], [$uploadedFile]);
You can mock UploadedFile so tests won't touch your disk at all. That's a trivial thing to do in many cases however not in this case )))
Mock and make a request is simple
// specify all methods you call in your code in the array below or use shouldReceive and etc methods
$uploadedFile1 = Mockery::mock(
'\Symfony\Component\HttpFoundation\File\UploadedFile',
[
'getClientOriginalName' => 'image-1.jpg',
'getClientOriginalExtension' => 'jpg',
]
);
// make a request
$response = $this->action(
'POST', 'YourController@store', [], [ ... your parameters ...], ['images' => [$uploadedFile1]]
);
Now the tricky part. You need to change how function 'filterFiles' in \Symfony\Component\HttpKernel\Client works. The easy way without changing framework code is changing tests/TestCase.php file the following way
<?php
/**
* {@inheritdoc}
*/
class MockedClient extends \Illuminate\Foundation\Testing\Client
{
/**
* {@inheritdoc}
*
* Skips any filtering and returns original files.
*/
protected function filterFiles(array $files)
{
return $files;
}
}
class TestCase extends \Illuminate\Foundation\Testing\TestCase
{
/**
* Creates the application.
*
* @return \Symfony\Component\HttpKernel\HttpKernelInterface
*/
public function createApplication()
{
$unitTesting = true;
$testEnvironment = 'testing';
return require __DIR__.'/../../bootstrap/start.php';
}
/**
* {@inheritdoc}
*/
protected function createClient(array $server = array())
{
return new MockedClient($this->app, $server);
}
}
Back to what @petercoles said, his solution needs to be completed with naming the name in the form for the file:
$uploadedFile = new Symfony\Component\HttpFoundation\File\UploadedFile('/path/to/file', 'original-file-name.ext');
$response = $this->call('POST', 'upload', [], ['file' => $uploadedFile]);
@nirradian I used your approach but now facing this error "FileNotFoundException in FileHandlerFactory.php" however file is there if I inspect $uploadedFile I see file path there, did I miss something?
@vaske here's what I did in my Laravel 5.1 unit test:
$file = new Symfony\Component\HttpFoundation\File\UploadedFile( storage_path( 'temp/test-file.csv' ), 'test-file.csv', 'text/plain', 446 );
$this->call( 'POST', '/upload', [], [], [ 'csv_file' => $file ] );
$this->assertResponseOk();
Just make sure you have the actual file in the specified location.
FYI, since I've been tearing my hair for 3 hours... you also have to specify the 6th constructing parameter as TRUE, so the UploadedFile class knows that you're uploading the image via unit testing environment.
$file = new Symfony\Component\HttpFoundation\File\UploadedFile( storage_path( 'temp/test-file.csv' ), 'test-file.csv', 'text/plain', 446, null, TRUE );
according to the class:
/* /vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Symphony/Component/HttpFoundation/File/UploadedFile.php */
...
public function __construct($path, $originalName, $mimeType = null, $size = null, $error = null, $test = false)
...
then the image upload via PHPUnit should work fine
I prefer the idea of mocking the upload as @EvgenyKovalev suggests. Any ideas how to do this in Laravel 5.1? I can't get it to work.
Thanks for adding that in, I was starting to get pretty annoyed
Sign in to participate in this thread!
The Laravel portal for problem solving, knowledge sharing and community building.
The community