20/02/2016 - PHPSPEC, SYMFONY
Phpspec ile içinde Request
ve ParameterBag
classlarınında olduğu kullanıcı isteklerini kontrol eden event listenerleri test etmek biraz zor olabilir. Bu örneğimizde kullanıcı contollere bir istek gönderiyor ve biz isteğin yolunu kesip, cevap göndermek yerine, hata mesajı gönderiyoruz. Bu kadar basit!
namespace Application\FrontendBundle\Controller;
use Application\FrontendBundle\Service\OrderService;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* @Route("order", service="application_frontend.controller.order")
*/
class OrderController
{
private $orderService;
public function __construct(OrderService $orderService)
{
$this->orderService = $orderService;
}
/**
* @param Request $request
*
* @Method({"POST"})
* @Route("/create/{car}", defaults={"car"="bmw"}, name="create_car_order")
*
* @return Response
*/
public function createAction(Request $request, $car)
{
return new Response(
'ORDERING:'.$car.PHP_EOL.
'PAYLOAD:'.$request->getContent().PHP_EOL.
'QUERY:'.$request->getQueryString()
);
}
}
Aşağıdaki isteği POST /order/create/mercedes?parent=mclaren
adresine gönderin.
{
"customer_name": "inanzzz",
"car_make": "mercedes",
"car_model": "sl500"
}
Status 200 OK
ORDERING:mercedes
PAYLOAD:{
"customer_name": "inanzzz",
"car_make": "mercedes",
"car_model": "sl500"
}
QUERY:parent=mclaren
namespace Application\FrontendBundle\EventListener;
use Application\FrontendBundle\Controller\OrderController;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
class OrderCreateListener
{
public function onKernelController(FilterControllerEvent $event)
{
$controller = $event->getController();
if (!is_array($controller)) {
return;
}
if (
$event->isMasterRequest() &&
$this->isOrderController($controller) &&
$this->isCreateCarMethod($event)
) {
$params = $event->getRequest()->attributes->get('_route_params');
$query = $event->getRequest()->getQueryString();
throw new BadRequestHttpException(
sprintf('PARAMS:%s - QUERY:%s', json_encode($params), $query)
);
}
return;
}
private function isOrderController(array $controller)
{
return $controller[0] instanceof OrderController ? true : false;
}
private function isCreateCarMethod(FilterControllerEvent $event)
{
return $event->getRequest()->attributes->get('_route') == 'create_car_order' ? true : false;
}
}
services:
application_frontend.event_listener.order_create:
class: Application\FrontendBundle\EventListener\OrderCreateListener
tags:
- { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
Aşağıdaki isteği POST /order/create/mercedes?parent=mclaren
adresine gönderin.
{
"customer_name": "inanzzz",
"car_make": "mercedes",
"car_model": "sl500"
}
Status 400 Bad Request
PARAMS:{"car":"mercedes"} - QUERY:parent=mclaren
400 Bad Request - BadRequestHttpException
Buradaki kritik nokta let()
fonksiyonudur. Her ne kadar controller ve listener içinde _construct()
methodu olmasada, testimizdeki it_should_throw_an_exception_if_a_user_calls_create_car_order_method_of_order_controller
fonksiyonunun doğru bir şekilde çalışması için gereklidir.
namespace spec\Application\FrontendBundle\EventListener;
use Application\FrontendBundle\Controller\OrderController;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
class OrderCreateListenerSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType('Application\FrontendBundle\EventListener\OrderCreateListener');
}
function let(Request $request, ParameterBag $attributes)
{
$request->attributes = $attributes;
$this->beConstructedWith();
}
function it_should_return_nothing_if_the_event_controller_is_not_an_array(
FilterControllerEvent $event
) {
$controller = null;
$event->getController()->willReturn(null);
$this->onKernelController($event)->shouldReturn(null);
}
function it_should_return_nothing_if_the_event_request_is_not_master_request(
FilterControllerEvent $event
) {
$controller = [];
$event->getController()->willReturn($controller);
$isMasterRequest = false;
$event->isMasterRequest()->willReturn($isMasterRequest);
$this->onKernelController($event)->shouldReturn(null);
}
function it_should_return_nothing_if_the_event_is_not_fired_for_order_controller(
FilterControllerEvent $event
) {
$controller = ['SomeController'];
$event->getController()->willReturn($controller);
$isMasterRequest = true;
$event->isMasterRequest()->willReturn($isMasterRequest);
$this->onKernelController($event)->shouldReturn(null);
}
function it_should_return_nothing_if_the_order_controller_event_is_not_fired_for_create_car_order_method_route(
FilterControllerEvent $event,
OrderController $orderController,
Request $request,
ParameterBag $attributes
) {
$controller = [$orderController];
$event->getController()->willReturn($controller);
$isMasterRequest = true;
$event->isMasterRequest()->willReturn($isMasterRequest);
$event->getRequest()->willReturn($request);
$route = 'some_route';
$attributes->get('_route')->shouldBeCalled()->willReturn($route);
$this->onKernelController($event)->shouldReturn(null);
}
function it_should_throw_an_exception_if_a_user_calls_create_car_order_method_of_order_controller(
FilterControllerEvent $event,
OrderController $orderController,
Request $request,
ParameterBag $attributes
) {
$controller = [$orderController];
$event->getController()->willReturn($controller);
$isMasterRequest = true;
$event->isMasterRequest()->willReturn($isMasterRequest);
$event->getRequest()->willReturn($request);
$route = 'create_car_order';
$attributes->get('_route')->shouldBeCalled()->willReturn($route);
$params = ['car' => 'mercedes'];
$attributes->get('_route_params')->shouldBeCalled()->willReturn($params);
$query = 'parent=mclaren';
$request->getQueryString()->willReturn($query);
$this->shouldThrow(
new BadRequestHttpException(
sprintf('PARAMS:%s - QUERY:%s', json_encode($params), $query)
)
)->during(
'onKernelController',
[$event]
);
}
}
inanzzz$ bin/phpspec run spec/Application/FrontendBundle/EventListener/OrderCreateListenerSpec.php -v
100% 6
1 specs
6 examples (6 passed)
50ms