Assume that we use an event listener to log user requests that hit CustomerController::getOneAction($id) endpoint/method in a text file and in application log. In this example we'll be just testing the event listener so just pay attention to it.


CustomerController


namespace Inanzzz\ApplicationBundle\Controller;

use Inanzzz\ApplicationBundle\Service\CustomerService;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\HttpFoundation\Response;

/**
* @Route("/customers", service="inanzzz_application.controller.customer")
*/
class CustomerController
{
private $customerService;

public function __construct(
CustomerService $customerService
) {
$this->customerService = $customerService;
}

/**
* @param int $id
*
* @Method({"GET"})
* @Route("/{id}", requirements={"id"="\d+"})
*
* @return Response
*/
public function getOneAction($id)
{
$result = $this->customerService->getOne($id);

return new Response(json_encode($result));
}
}

services:
inanzzz_application.controller.customer:
class: Inanzzz\ApplicationBundle\Controller\CustomerController
arguments:
- "@inanzzz_application.service.customer"

CustomerControllerListener


namespace Inanzzz\ApplicationBundle\Listener;

use Inanzzz\ApplicationBundle\Controller\CustomerController;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

class CustomerControllerListener
{
private $logger;
private $logFilePath;

public function __construct(
LoggerInterface $logger,
$logFilePath
) {
$this->logger = $logger;
$this->logFilePath = $logFilePath;
}

public function onKernelController(
FilterControllerEvent $event
) {
if (!is_array($event->getController())) {
return;
}

if (!isset($event->getController()[0])) {
return;
}

if (!$event->getController()[0] instanceof CustomerController) {
return;
}

if (!$event->isMasterRequest()) {
return;
}

$request = $event->getRequest();

$id = $request->get('id');
if (!$id) {
return;
}

$this->log($id);
}

private function log($id)
{
$message = sprintf('Customer [%s] is called.', $id);

$this->logger->info($message);
file_put_contents($this->logFilePath, $message.PHP_EOL, FILE_APPEND);
}
}

services:
inanzzz_application.listener.customer_controller:
class: Inanzzz\ApplicationBundle\Listener\CustomerControllerListener
tags:
- { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
arguments:
- "@logger"
- "%kernel.root_dir%/../var/logs/customer.log"

Log file


As you can see above, the logs are saved in /var/logs/customer.log file in live environment but we'll mock it in our test environment. Create a file called /tests/Inanzzz/ApplicationBundle/Mock/log/customer.log so that our tests can save logs into.


CustomerControllerListenerTest


namespace tests\Inanzzz\ApplicationBundle\Command;

use Inanzzz\ApplicationBundle\Controller\CustomerController;
use Inanzzz\ApplicationBundle\Listener\CustomerControllerListener;
use Inanzzz\ApplicationBundle\Service\CustomerService;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use stdClass;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;

class CustomerControllerListenerTest extends TestCase
{
const LOG_PATTERN = 'Customer [%s] is called.';
const LOG_FILE_PATH = __DIR__.'/../Mock/log/customer.log';

/** @var CustomerControllerListener */
private $customerControllerListener;

protected function setUp()
{
/** @var LoggerInterface $loggerInterfaceMock */
$loggerInterfaceMock = $this->getMockBuilder(LoggerInterface::class)
->disableOriginalConstructor()
->getMock();

$this->customerControllerListener = new CustomerControllerListener(
$loggerInterfaceMock,
self::LOG_FILE_PATH
);
}

protected function tearDown()
{
$this->customerControllerListener = null;
file_put_contents(self::LOG_FILE_PATH, null);
}

public function testOnKernelControllerWillReturnNullIfEventControllerIsNull()
{
/** @var FilterControllerEvent|\PHPUnit_Framework_MockObject_MockObject $filterControllerEventMock */
$filterControllerEventMock = $this->getMockBuilder(FilterControllerEvent::class)
->disableOriginalConstructor()
->getMock();

$filterControllerEventMock
->expects($this->once())
->method('getController')
->willReturn(null);

$result = $this->customerControllerListener->onKernelController($filterControllerEventMock);

$this->assertNull($result);
}

public function testOnKernelControllerWillReturnNullIfEventControllerIsEmptyArray()
{
/** @var FilterControllerEvent|\PHPUnit_Framework_MockObject_MockObject $filterControllerEventMock */
$filterControllerEventMock = $this->getMockBuilder(FilterControllerEvent::class)
->disableOriginalConstructor()
->getMock();

$filterControllerEventMock
->expects($this->exactly(2))
->method('getController')
->willReturn([]);

$result = $this->customerControllerListener->onKernelController($filterControllerEventMock);

$this->assertNull($result);
}

public function testOnKernelControllerWillReturnNullIfEventControllerIsInvalidObject()
{
/** @var FilterControllerEvent|\PHPUnit_Framework_MockObject_MockObject $filterControllerEventMock */
$filterControllerEventMock = $this->getMockBuilder(FilterControllerEvent::class)
->disableOriginalConstructor()
->getMock();

$filterControllerEventMock
->expects($this->exactly(3))
->method('getController')
->willReturn([new stdClass()]);

$result = $this->customerControllerListener->onKernelController($filterControllerEventMock);

$this->assertNull($result);
}

public function testOnKernelControllerWillReturnNullIfRequestIsNotMaster()
{
/** @var HttpKernelInterface $httpKernelInterfaceMock */
$httpKernelInterfaceMock = $this->getMockBuilder(HttpKernelInterface::class)
->disableOriginalConstructor()
->getMock();

/** @var CustomerService $customerServiceMock */
$customerServiceMock = $this->getMockBuilder(CustomerService::class)
->disableOriginalConstructor()
->getMock();
$customerController = new CustomerController($customerServiceMock);
$callable = [$customerController, 'getOneAction'];

/** @var Request $requestMock */
$requestMock = $this->getMockBuilder(Request::class)
->disableOriginalConstructor()
->getMock();

$filterControllerEvent = new FilterControllerEvent(
$httpKernelInterfaceMock,
$callable,
$requestMock,
HttpKernelInterface::SUB_REQUEST
);

$result = $this->customerControllerListener->onKernelController($filterControllerEvent);

$this->assertNotEquals(HttpKernelInterface::MASTER_REQUEST, $filterControllerEvent->isMasterRequest());
$this->assertNull($result);
}

public function testOnKernelControllerWillReturnNullIfRequestIdParameterIsMissing()
{
/** @var FilterControllerEvent|\PHPUnit_Framework_MockObject_MockObject $filterControllerEventMock */
$filterControllerEventMock = $this->getMockBuilder(FilterControllerEvent::class)
->disableOriginalConstructor()
->getMock();

/** @var CustomerController|\PHPUnit_Framework_MockObject_MockObject $customerControllerMock */
$customerControllerMock = $this->getMockBuilder(CustomerController::class)
->disableOriginalConstructor()
->getMock();

/** @var Request|\PHPUnit_Framework_MockObject_MockObject $requestMock */
$requestMock = $this->getMockBuilder(Request::class)
->disableOriginalConstructor()
->getMock();

$filterControllerEventMock
->expects($this->exactly(3))
->method('getController')
->willReturn([$customerControllerMock]);

$filterControllerEventMock
->expects($this->once())
->method('isMasterRequest')
->willReturn(HttpKernelInterface::MASTER_REQUEST);

$filterControllerEventMock
->expects($this->once())
->method('getRequest')
->willReturn($requestMock);

$requestMock
->expects($this->once())
->method('get')
->with('id')
->willReturn(null);

$result = $this->customerControllerListener->onKernelController($filterControllerEventMock);

$this->assertNull($result);
}

public function testOnKernelControllerWillLogRequest()
{
/** @var FilterControllerEvent|\PHPUnit_Framework_MockObject_MockObject $filterControllerEventMock */
$filterControllerEventMock = $this->getMockBuilder(FilterControllerEvent::class)
->disableOriginalConstructor()
->getMock();

/** @var CustomerController|\PHPUnit_Framework_MockObject_MockObject $customerControllerMock */
$customerControllerMock = $this->getMockBuilder(CustomerController::class)
->disableOriginalConstructor()
->getMock();

/** @var Request|\PHPUnit_Framework_MockObject_MockObject $requestMock */
$requestMock = $this->getMockBuilder(Request::class)
->disableOriginalConstructor()
->getMock();

$filterControllerEventMock
->expects($this->exactly(3))
->method('getController')
->willReturn([$customerControllerMock]);

$filterControllerEventMock
->expects($this->once())
->method('isMasterRequest')
->willReturn(HttpKernelInterface::MASTER_REQUEST);

$filterControllerEventMock
->expects($this->once())
->method('getRequest')
->willReturn($requestMock);

$id = 123;

$requestMock
->expects($this->once())
->method('get')
->with('id')
->willReturn($id);

$result = $this->customerControllerListener->onKernelController($filterControllerEventMock);

$this->assertEquals(
sprintf(self::LOG_PATTERN, $id),
trim(file_get_contents(self::LOG_FILE_PATH))
);
$this->assertNull($result);
}
}

Result


$ vendor/bin/phpunit
PHPUnit 4.8.36 by Sebastian Bergmann and contributors.

...................

Time: 396 ms, Memory: 8.00MB

OK (19 tests, 44 assertions)