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

问题描述 投票:16回答:3

我正在用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() (甚至是其他函数)来向服务器发送请求?

symfony streaming symfony-2.1 functional-testing
3个回答
16
投票

该函数的返回值是 sendContent (而不是 getContent)是你设置的回调。getContent 实际上只是返回 假的 在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是 此处


9
投票

对我来说不是这样的。相反,我在请求之前使用了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文件.

在controller中:这是因为我的响应是一个cv文件。

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

0
投票

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

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

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

希望能帮到大家

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

© www.soinside.com 2019 - 2024. All rights reserved.