我有以下路线:
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();
然而,在单元测试中这看起来是非常草率的事情。
以前有没有人遇到过这种情况?是否可以测试流响应的内容?
发布于 2018-08-16 17:59:35
这不是一个好的解决方案,更像是一种黑客行为,但如果其他人遇到这个问题,你可以这样做:
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
}
发布于 2021-04-14 21:48:49
参加聚会有点晚了,但这可能会对别人有帮助。
在Laravel中,你可以在处理StreamedResponse
时使用$response->streamedContent()
(我相信从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 (bc,很明显是CSV ),但我相信你也可以用Json或其他工具做同样的事情。
https://stackoverflow.com/questions/51857346
复制相似问题