I have the following code in one of my routes:
return Response::download('cv.pdf');
Any idea how to test this? I've tried to use shouldReceive() but that doesn't seem to work ('shouldReceive() undefined function....').
I have the following code in one of my routes:
return Response::download('cv.pdf');
Any idea how to test this? I've tried to use shouldReceive() but that doesn't seem to work ('shouldReceive() undefined function....').
EDIT: As pointed by @DavidBarker in his comment to the OP question
The Illuminate\Support\Facades\Response class doesn't actually extend Illuminate\Support\Facades\Facade so doesnt have the shouldRecieve() method. You need to test the response of this route after calling it in a test.
So if you want to test your download functionality, you can try checking the response for errors with:
$this->assertTrue(preg_match('/(error|notice)/i', $response) === false);
$response->assertDownload()
was added in Laravel 8.45.0:
Assert that the response is a "download". Typically, this means the invoked route that returned the response returned a Response::download response, BinaryFileResponse, or Storage::download response:
$response->assertDownload();
Learn More:
https://laravel.com/docs/8.x/http-tests#assert-download
It does not currently (2023) allow one to test the contents of the file, but you can use test mocks for that:
public function test_successful_download(): void
{
$this->authenticateAsAdmin();
$this->instance(
ResponseFactory::class,
Mockery::mock(ResponseFactory::class, static function(MockInterface $mock) {
$mock
->shouldReceive('download')
->with('[[ FILE CONTENTS ]]', '[[ FILE NAME]]')
->once()
;
}),
);
$this->call('POST', route('my-download-csv'));
}
# mycontroller.php
// ...
public function downloadCsv(Request $request)
{
return response()->download('[[ FILE CONTENTS ]]', '[[ FILE NAME]]');
}
// ...
OK (1 test, 1 assertion)
text/plain
, there might be a way to test the content. But if the content has something like application/octet-stream
then I don't think you can test that. –
Fortuneteller EDIT: As pointed by @DavidBarker in his comment to the OP question
The Illuminate\Support\Facades\Response class doesn't actually extend Illuminate\Support\Facades\Facade so doesnt have the shouldRecieve() method. You need to test the response of this route after calling it in a test.
So if you want to test your download functionality, you can try checking the response for errors with:
$this->assertTrue(preg_match('/(error|notice)/i', $response) === false);
You can assert that the status code is 200
$this->assertEquals($response->getStatusCode(), 200);
because sometimes you might have some data returned that match "error" or "notice" and that would be misleading.
I additionally assert that there's an attachment
in the response headers:
$this->assertContains('attachment', (string)$response);
$this->assertEquals('attachment; filename=cv.pdf', $response->headers->get('content-disposition'));
–
Inflationary $response->assertHeader('content-disposition', 'attachment; filename=cv.pdf');
–
Jefferey You can use Mockery
to mock the download
method, for this you will need to mock ResponseFactory
.
public function testDownloadCsv()
{
$this->instance(
ResponseFactory::class, Mockery::mock(ResponseFactory::class, function ($mock) {
$mock->shouldReceive('download')
->once()
->andReturn(['header' => 'data']);
}));
$response = $this->get('/dowload-csv');
$response->assertStatus(Response::HTTP_OK);
$response->assertJson(['header' => 'data']); // Response
}
© 2022 - 2024 — McMap. All rights reserved.
Illuminate\Support\Facades\Response
class doesn't actually extendIlluminate\Support\Facades\Facade
so doesnt have theshouldRecieve()
method. You need to test the response of this route after calling it in a test. – ShellbackshouldRecieve()
now – Wallacewallach