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

时间:2013-03-31 21:23:02

标签: symfony streaming symfony-2.1 functional-testing

我正在用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 test client请求内容,如下所示:

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

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

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

3 个答案:

答案 0 :(得分:12)

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

您可以在输出缓冲区here

上阅读更多内容

StreamResponse的API为here

答案 1 :(得分: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);

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

在控制器中:

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

答案 2 :(得分:1)

目前最好的答案过去一段时间对我来说一直很有效,但是由于某种原因,它不再适用了。响应被解析为DOM搜寻器,并且二进制数据丢失。

我可以使用内部回复来解决此问题。这是我所做更改的git补丁[1]:

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

我希望这可以帮助某人。

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