如何使用Symfony测试客户端检索流式响应(例如,下载文件)

Lor*_*ori 15 streaming functional-testing symfony symfony-2.1

我正在用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;
}
Run Code Online (Sandbox Code Playgroud)

在功能测试中,我尝试使用Symfony测试客户端请求内容,如下所示:

$client = static::createClient();
$client->request('GET', $url);
$content = $client->getResponse()->getContent();
Run Code Online (Sandbox Code Playgroud)

问题是它$content是空的,我猜是因为客户端收到HTTP头后立即生成响应,而不等待传递数据流.

有没有办法捕获流式响应的内容,同时仍然使用$client->request()(甚至一些其他功能)将请求发送到服务器?

hob*_*nob 13

sendContent(而不是getContent)的返回值是您设置的回调.getContent实际上只是在Symfony2中返回false

使用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();
Run Code Online (Sandbox Code Playgroud)

您可以在此处阅读有关输出缓冲区的更多信息

StreamResponse的API就在这里

  • 为了让我能够工作,我必须在发出请求之前放置ob_start(). (3认同)

Ben*_*fez 11

当前的最佳答案曾经对我有用一段时间,但由于某种原因它不再有效了。响应被 DOM 爬虫解析,二进制数据丢失。

我可以通过使用内部响应来解决这个问题。这是我的更改的 git 补丁[1]:

-        ob_start();
         $this->request('GET', $uri);
-        $responseData = ob_get_clean();
+        $responseData = self::$client->getInternalResponse()->getContent();
Run Code Online (Sandbox Code Playgroud)

我希望这可以帮助别人。

[1]:你只需要访问客户端,这是一个 Symfony\Bundle\FrameworkBundle\KernelBrowser


Mon*_*arc 8

对我来说不是那样的.相反,我在发出请求之前使用了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);
Run Code Online (Sandbox Code Playgroud)

也许这是因为我的回复是一个csv文件.

在控制器中:

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