开发者

Testing File uploads in Symfony2

开发者 https://www.devze.com 2023-03-24 12:32 出处:网络
In the Symfony2 documentation it gives the simple example of: $client->request(\'POST\', \'/submit\', array(\'name\' => \'Fabien\'), array(\'photo\' => \'/path/to/photo\'));

In the Symfony2 documentation it gives the simple example of:

$client->request('POST', '/submit', array('name' => 'Fabien'), array('photo' => '/path/to/photo'));

To simulate a file upload.

However in all my tests I am getting nothing in the $request object in the app and nothing in the $_FILES array.

Here is a simple WebTestCase which is failing. It is self contained and tests the request that the $client constructs based on the parameters you pass in. It's not testing the app.

class UploadTest extends WebTestCase {

    public function testNewPhotos() {
        $client = $this->createClient();
        $client->request(
            'POST', 
            '/submit', 
            array('name' => 'Fabien'), 
            array('photo' => __FILE__)
        );

        $this->assertEquals(1, count($client->getRequest()->files->all()));
    }
}

Just to be clear. This is not a question about how to do file uploads, that I can do. It is about how to 开发者_StackOverflowtest them in Symfony2.

Edit

I'm convinced I'm doing it right. So I've created a test for the Framework and made a pull request. https://github.com/symfony/symfony/pull/1891


This was an error in the documentation.

Fixed here:

use Symfony\Component\HttpFoundation\File\UploadedFile;

$photo = new UploadedFile('/path/to/photo.jpg', 'photo.jpg', 'image/jpeg', 123);
// or
$photo = array('tmp_name' => '/path/to/photo.jpg', 'name' => 'photo.jpg', 'type' => 'image/jpeg', 'size' => 123, 'error' => UPLOAD_ERR_OK);

$client = static::createClient();
$client->request('POST', '/submit', array('name' => 'Fabien'), array('photo' => $photo));

Documentation here


Here is a code which works with Symfony 2.3 (I didn't tried with another version):

I created an photo.jpg image file and put it in Acme\Bundle\Tests\uploads.

Here is an excerpt from Acme\Bundle\Tests\Controller\AcmeTest.php:

function testUpload()
{
    // Open the page
    ...

    // Select the file from the filesystem
    $image = new UploadedFile(
        // Path to the file to send
        dirname(__FILE__).'/../uploads/photo.jpg',
        // Name of the sent file
        'filename.jpg',
        // MIME type
        'image/jpeg',
        // Size of the file
        9988
    );

    // Select the form (adapt it for your needs)
    $form = $crawler->filter('input[type=submit]...')->form();

    // Put the file in the upload field
    $form['... name of your field ....']->upload($image);

    // Send it
    $crawler = $this->client->submit($form);

    // Check that the file has been successfully sent
    //  (in my case the filename is displayed in a <a> link so I check
    //  that it appears on the page)
    $this->assertEquals(
        1,
        $crawler->filter('a:contains("filename.jpg")')->count()
    );
}


Even if the question is related to Symfony2, it appears in the top results when searching for Symfony4 in Google.

Instancing an UploadedFile works, but the shortest way I found was also actually in the official documentation:

$crawler = $client->request('GET', '/post/hello-world');
$buttonCrawlerNode = $crawler->selectButton('submit');
$form = $buttonCrawlerNode->form();
$form['photo']->upload('/path/to/lucas.jpg');

https://symfony.com/doc/current/testing.html#forms


I found this article, https://coderwall.com/p/vp52ew/symfony2-unit-testing-uploaded-file, and works perfect.

Regards


if you want to mock a UploadedFile without a client request, you can use:

    $path = 'path/to/file.test';
    $originalName = 'original_name.test';
    $file = new UploadedFile($path, $originalName, null, UPLOAD_ERR_OK, true);
    $testSubject->method($file);
0

精彩评论

暂无评论...
验证码 换一张
取 消