Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to retrieve a streamed response (e.g. download a file) with Symfony test client

I am writing functional tests with Symfony2.

I have a controller that calls a getImage() function which streams an image file as follows:

public function getImage($filePath)
    $response = new StreamedResponse();
    $response->headers->set('Content-Type', 'image/png');

    $response->setCallback(function () use ($filePath) {
        $bytes = @readfile(filePath);
        if ($bytes === false || $bytes <= 0)
            throw new NotFoundHttpException();
    });

    return $response;
}

In functional testing, I try to request the content with the Symfony test client as follows:

$client = static::createClient();
$client->request('GET', $url);
$content = $client->getResponse()->getContent();

The problem is that $content is empty, I guess because the response is generated as soon as the HTTP headers are received by the client, without waiting for a data stream to be delivered.

Is there a way to catch the content of the streamed response while still using $client->request() (or even some other function) to send the request to the server?

like image 899
Lorenzo Polidori Avatar asked Mar 31 '13 21:03

Lorenzo Polidori


2 Answers

The return value of sendContent (rather than getContent) is the callback that you've set. getContent actually just returns false in Symfony2

Using sendContent you can enable the output buffer and assign the content to that for your tests, like so:

$client = static::createClient();
$client->request('GET', $url);

// Enable the output buffer
ob_start();
// Send the response to the output buffer
$client->getResponse()->sendContent();
// Get the contents of the output buffer
$content = ob_get_contents();
// Clean the output buffer and end it
ob_end_clean();

You can read more on the output buffer here

The API for StreamResponse is here

like image 177
hobnob Avatar answered Oct 28 '22 02:10

hobnob


For me didn't work like that. Instead, I used ob_start() before making the request, and after the request i used $content = ob_get_clean() and made asserts on that content.

In test:

    // Enable the output buffer
    ob_start();
    $this->client->request(
        'GET',
        '$url',
        array(),
        array(),
        array('CONTENT_TYPE' => 'application/json')
    );
    // Get the output buffer and clean it
    $content = ob_get_clean();
    $this->assertEquals('my response content', $content);

Maybe this was because my response is a csv file.

In controller:

    $response->headers->set('Content-Type', 'text/csv; charset=utf-8');
like image 10
M. Marc Avatar answered Oct 28 '22 03:10

M. Marc