Тестирование Symfony5, PHPUnit и PhpSpreadsheet - двоичный ответ отображается в консоли - PullRequest
0 голосов
/ 02 апреля 2020

Я подготовил простой функциональный тест для проверки состояния контроллера, который возвращает документ Excel в ответ:

<?php

namespace App\Tests\Controller;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class CustomersControllerTest extends WebTestCase
{

    private $client = null;

    public function setUp()
    {
        $this->client = static::createClient([], [
            'PHP_AUTH_USER' => USERNAME,
            'PHP_AUTH_PW'   => PASSWORD
        ]);

    }

    public function testActivityEXCEL()
    {

        $this->client->request('GET', '/customers/activity-excel');
        $this->assertEquals(200, $this->client->getResponse()->getStatusCode());

    }

}

Контроллер возвращает документ Excel, созданный https://phpspreadsheet.readthedocs.io/en/latest/:

/**
 * @Route("/activity-excel", name="customers_activity_excel")
 * @Security("is_granted('ROLE_RFM_CUSTOMERS_ACTIVE_INACTIVE')")
 * 
 * @param TranslatorInterface $translator
 * @param ChartManager $chartManager
 * 
 * @return JsonResponse
 */
public function activityEXCEL(TranslatorInterface $translator, ChartManager $chartManager)
{

    $filters = array();

    foreach($this->get('session')->all() as $key => $value){
        if (strpos($key, 'customers_activity_') !== false) {
            $filters[str_replace('customers_activity_', '', $key)] = $value;
        }
    }

    $data = $chartManager->activityChart($filters);

    $spreadsheet = new Spreadsheet();
    $sheet = $spreadsheet->getActiveSheet();

    $sheet->setCellValue('A1', $translator->trans('general.information'))->getStyle('A1')->getFont()->setBold(true);
    $sheet->setCellValue('A2', $translator->trans('view'));
    $sheet->setCellValue('A3', $translator->trans('chart.type'));
    $sheet->setCellValue('A4', $translator->trans('from'));
    $sheet->setCellValue('A5', $translator->trans('to'));
    $sheet->setCellValue('A6', $translator->trans('chart.active'));
    $sheet->setCellValue('A7', $translator->trans('chart.inactive'));

    $sheet->setCellValue('B2', $data['table']['view'] == 1 ? $translator->trans('for.months') : $translator->trans('everybody'));
    $sheet->setCellValue('B3', $translator->trans($data['table']['type']));
    $sheet->setCellValue('B4', $data['table']['date_from']);
    $sheet->setCellValue('B5', $data['table']['date_to']);
    $sheet->setCellValue('B6', $data['table']['active']);
    $sheet->setCellValue('B7', $data['table']['inactive']);

    if($data['table']['monthly']){

        $sheet->setCellValue('A9', $translator->trans('table.month'))->getStyle('A9')->getFont()->setBold(true);
        $sheet->setCellValue('B9', $translator->trans('active'))->getStyle('B9')->getFont()->setBold(true);    
        $sheet->setCellValue('C9', $translator->trans('inactive'))->getStyle('C9')->getFont()->setBold(true);  

        $i = 10;

        foreach($data['table']['dataset'] as $item){

            $sheet->setCellValue('A'.$i, $item['label']);
            $sheet->setCellValue('B'.$i, $item['data'][0]);
            $sheet->setCellValue('C'.$i, $item['data'][1]);

            $i++;
        }

    }

    $img = $chartManager->preparePng($filters['img']);

    $drawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
    $drawing->setName('Chart');
    $drawing->setDescription('Chart');
    $drawing->setPath($img['path']);
    $drawing->setWidth($img['width']*0.6);
    $drawing->setHeight($img['height']*0.6);
    $drawing->setCoordinates('G2');
    $drawing->setWorksheet($spreadsheet->getActiveSheet());

    $writer = new Xlsx($spreadsheet);

    $response =  new StreamedResponse(
        function () use ($writer) {
            $writer->save('php://output');
        }
    );

    $response->headers->set('Content-Type', 'application/vnd.ms-excel');
    $response->headers->set('Content-Disposition', 'attachment; filename="Report_'.date("m_d_Y").'.xlsx"');
    $response->headers->set('Cache-Control','max-age=0');

    return $response;

}

Тест выполнен правильно, однако двоичное значение файла отображается в консоли.

enter image description here

Как исправить эту ошибку или как правильно протестировать аналогичные контроллеры?

EDIT

Спасибо за @Jakumi Я нашел решение. Виновен StreamedResponse php: // вывод. Теперь мой тест выглядит так:

/**
 * @dataProvider provideFilters
 */
public function testActivityEXCEL($filters)
{

    $session = $this->client->getContainer()->get('session');

    foreach($filters as $key => $value){
        $session->set($key, $value);
    }

    ob_start();
    $this->client->request('GET', '/customers/activity-excel');
    $response = ob_get_clean();

    $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
    $this->assertSame(true, !ctype_print($response));

}

Надеюсь, это кому-нибудь поможет

...