Testing Laravel-Excel download
I am using the following package: https://github.com/Maatwebsite/Laravel-Excel in version 2 with Laravel 5.1
I have a controller method with the following code:
....
return Excel::create('List', function($excel) use ($list)
{
$excel->sheet('List', function($sheet) use ($list)
{
$sheet->fromModel($list);
});
})
->download('csv');
and a simple test:
$this->call('GET', 'route/to/csv', [
'param' => 'value',
]);
$this->dump();
Above test outputs [ERROR]: Headers already sent
from this line of the package.
The controller method works fine but can't test it.
I tried to run phpunit with a parameter --stderr
. In this case, no error occurs, but it just dumps the output of the CSV file to the console and exits. I also tried to run the test with annotation @runInSeparateProcess
and got errors like:
PHPUnit_Framework_Exception: PHP Notice: Constant LARAVEL_START already defined in bootstrap/autoload.php on line 3
....
PHP Fatal error: Uncaught exception 'ReflectionException' with message 'Class env does not exist' in vendor/laravel/framework/src/Illuminate/Container/Container.php:736
Could this be a bug in the Laravel-Excel package or am I testing it wrong?
source to share
This is because the method download
works in laravel-excel by setting headers. You want to avoid this, and instead do all your work by returning responses to laravel.
Try this instead:
$file = Excel::create('List', function($excel) use ($list) {
$excel->sheet('List', function($sheet) use ($list)
{
$sheet->fromModel($list);
});
})->string('xls');
return new Response($file, 200, [
'Content-Type' => 'application/vnd.ms-excel; charset=UTF-8',
'Content-Disposition' => 'attachment; filename="' . $file->filename . '.' . $file->ext . '"',
'Expires' => 'Mon, 26 Jul 1997 05:00:00 GMT', // Date in the past
'Last-Modified' => Carbon::now()->format('D, d M Y H:i:s'),
'Cache-Control' => 'cache, must-revalidate',
'Pragma' => 'public',
]);
The key difference is the use of a method string()
that will return binary data for the excel file and allow it to be passed as data for the response.
source to share