我有以下路线:
Route::get('echo',function (Request $req) {
return response()->stream(function () use ($req) {
echo json_encode($req->all());
}, 200, [
'Content-Type' => 'application/json'
]);
})->name('echo');
为简单起见,让我们假设它是一个简单的回声响应。实际上,这是一个非常大的文件。两种情况下的结果都是相同的。
现在我要测试此路由,以查看是否确实可以看到json内容,所以我尝试了以下方法:
public function testBasicTest()
{
$response = $this->get(route('echo', [
"content"=>"some content"
]));
$response->assertSeeText("some content"); //Doesn't work
$response->assertJson( [
"content"=>"some content"
]); //Neither does this
}
我已经对其进行了进一步检查,这似乎是因为(a)响应被包裹在TestResponse
周围(b)响应内容从未流过,并且(c)即使响应内容是要通过$response->baseResponse->sendContent()
强制流式传输,则实际返回的内容实际上并未被TestResponse
另外,调用$response->getContent()
不起作用,因为它似乎直接调用了StreamedResponse::getContent()
,后者被硬编码为返回false
。
使用以下方法,我取得了一些有限的成功:
ob_start();
$response->sendContent();
$result = ob_get_clean();
但是,在单元测试中,这看起来很草率。
之前有人遇到过吗?是否可以测试流式响应的内容?
答案 0 :(得分:2)
这不是一个好的解决方案,更像是一个hack,但是如果其他任何人遇到此问题,您可以执行以下操作:
public function testBasicTest()
{
$response = $this->get(route('echo', [
"content"=>"some content"
]));
if ($response->baseResponse instanceof StreamedResponse) {
ob_start();
$response->sendContent();
$content = ob_get_clean();
$response = new TestResponse(
new Response($content,
$response->baseResponse->getStatusCode(),
$response->baseResponse->headers->all()
)
);
}
$response->assertSee("some content"); //Works
}
答案 1 :(得分:2)
聚会有点晚,但可能会帮助其他人。
在 Laravel 中,您可以在处理 $response->streamedContent()
时执行 StreamedResponse
(我相信从 5.8 开始)。
即使我的调试器告诉我响应的流式内容是 null
,我仍然从中获取数据。
就我而言,它是 CSV,所以在我完成的功能测试中:
$res = $this->post('api/v1/entity/export', $payload, $header);
$res->assertStatus(200);
$res->assertHeader('Content-Disposition', 'attachment; filename=entity.csv');
$reader = Reader::createFromString($res->streamedContent());
// tests...
我使用了 LeagueCSV(显然它是 CSV),但我相信你可以用 Json 或其他方式做同样的事情。