我正在用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()
(甚至一些其他功能)将请求发送到服务器?
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();
你可以在这里阅读更多关于输出缓冲区的信息
StreamResponse的API在这里
对我来说不是这样的。相反,我在发出请求之前使用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');
目前最好的答案曾经在一段时间内对我很有效,但由于某种原因,它不再适用了。响应被解析为DOM爬虫,二进制数据丢失。
我可以通过使用内部响应来修复它。这是我的改动的git补丁[1]:
- ob_start();
$this->request('GET', $uri);
- $responseData = ob_get_clean();
+ $responseData = self::$client->getInternalResponse()->getContent();
我希望这能帮助到别人。
[1]:您只需要访问客户端,这是一个SymfonyBundleFrameworkBundleKernelBrowser