Как получить потоковый ответ (например, загрузить файл) с помощью тестового клиента Symfony

Я пишу функциональные тесты с помощью Symfony2.

У меня есть контроллер, который вызывает функцию getImage(), которая передает файл изображения следующим образом:

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;
}

В функциональном тестировании я пытаюсь запросить контент с помощью клиента тестирования Symfony следующим образом:

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

Проблема заключается в том, что $content пуст, я думаю, потому что ответ генерируется, как только HTTP-заголовки принимаются клиентом, не дожидаясь доставки потока данных.

Есть ли способ улавливать содержимое потокового ответа при использовании $client->request() (или даже какой-либо другой функции) для отправки запроса на сервер?

Ответ 1

Возвращаемое значение sendContent (а не getContent) - это обратный вызов, который вы установили. getContent фактически просто возвращает false в Symfony2

С помощью sendContent вы можете включить выходной буфер и назначить контент для своих тестов, например:

$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();

Вы можете больше узнать о выходном буфере здесь

API для StreamResponse здесь

Ответ 2

Для меня это не сработало. Вместо этого я использовал ob_start() перед тем, как сделать запрос, и после запроса я использовал $content = ob_get_clean() и сделал утверждения по этому контенту.

В тесте:

    // 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);

Возможно, это было потому, что мой ответ - это файл csv.

В контроллере:

    $response->headers->set('Content-Type', 'text/csv; charset=utf-8');