18

我正在用 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()(甚至某些其他功能)将请求发送到服务器的同时捕获流响应的内容?

4

3 回答 3

22

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

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

StreamResponse 的 API 在这里

于 2013-08-16T16:14:55.443 回答
10

对我来说不是那样工作的。相反,我在发出请求之前使用了 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');
于 2015-05-26T10:12:54.500 回答
2

当前的最佳答案在一段时间内对我来说效果很好,但由于某种原因它不再适用了。响应被解析为 DOM 爬虫,二进制数据丢失。

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

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

我希望这可以帮助某人。

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

于 2020-04-24T16:33:24.147 回答