当前位置: 首页 > 知识库问答 >
问题:

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

唐珂
2023-03-14

我正在用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-的情况下捕获流响应的内容-


共有3个答案

万德海
2023-03-14

目前最好的答案曾经在一段时间内对我很有效,但出于某种原因,现在不再有效了。响应被解析为DOM爬虫,二进制数据丢失。

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

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

我希望这能帮助别人。

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

姬昊焱
2023-03-14

对我来说不是那样的。相反,我在提出请求之前使用了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');
毛宏达
2023-03-14

sendContent(而不是getContent)的返回值是您设置的回调。在Symfony2中,getContent实际上只返回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();

您可以在这里阅读更多关于输出缓冲区的信息

流响应的API在这里

 类似资料:
  • 我正在spring应用程序中使用web客户端 我在执行相同操作时面临内存泄漏问题 我正在使用下面的代码获取来自服务的非2xx响应的响应体: 我的问题是,如果我在responseMono上使用dispose方法,处理过程需要很长的时间,而没有它,我会面临内存泄漏问题。我在这里做错什么了吗?

  • 我有spring boot控制器 在其中,我使用服务,该服务反过来使用ktor客户端向外部服务器发送post请求,该服务器应响应发送csv文件。csv文件内容取决于我在myObjectRq中发送的值。 服务: 正确设置响应的标头,以及日志。方法中的info(String(response.content.toByteArray())打印出接收文件的内容,但我不能将其设置为HttpServletRe

  • 我知道这是不好的做法和特征识别应该是建设网站的方式。然而,这不是我的用例。 我有我的浏览器扩展的不同发行版,我想根据他们当前的浏览器更改下载按钮。 我试过使用,事实证明这是非常没用的,因为大多数浏览器都设置了所有流行的用户代理。例如chrome就有这个。 我见过很多网站的下载按钮上都有这个功能。如何做到这一点呢? 编辑:我现在了解了为什么“mozzila/x.x”位于userAgent字符串开头的

  • 例如,在本文中,我试图理解为什么在流中使用flatmap()(直接从引用中粘贴副本) AFAIK,应用于流的平面图会为流中的每个输入值产生任意数量的值(0... n)。所以一个平面图需要一个产生流的函数。 通量发射0个或多个项目,然后可选地完成或偏离。 那么,响应流上到底发生了什么?这是接收响应流并发出0个或更多类警报对象的函数吗?因此,如果我们

  • 问题内容: 我想在用户单击允许他们下载文件的超链接后将用户重定向到其他网页。但是,由于它们需要在打开/保存文件对话框中进行选择,因此在它们接受下载之前,我不希望它们重定向。 我如何检测到他们执行了此操作? 问题答案: 正如我多年维护download.js所发现的那样,根本 无法 通过JS 来告诉用户 (或可能通常参见下文),用户选择如何使用下载“打开/保存”对话框。这是一个常见的功能请求,多年来我

  • 本文向大家介绍Java下http下载文件客户端和上传文件客户端实例代码,包括了Java下http下载文件客户端和上传文件客户端实例代码的使用技巧和注意事项,需要的朋友参考一下 一、下载客户端代码 上述代码只适合下载小文件,如果下载大文件则会出现  Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 错误,所以