Skip to content

Instantly share code, notes, and snippets.

@silviuvoicu
Created August 20, 2013 07:39
Show Gist options
  • Save silviuvoicu/6278223 to your computer and use it in GitHub Desktop.
Save silviuvoicu/6278223 to your computer and use it in GitHub Desktop.
Spec with phpspec a symfony2 controller. I know which is the normal work flow: write first the spec, and then the code, but in order to understand better how to spec a symfony2 controller, I first create a simple book entity with just id and name, and then with the help of generators I created a crud system, which I modified a little. Then havin…
<?php
namespace Acme\DemoBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Acme\DemoBundle\Entity\Book;
use Acme\DemoBundle\Form\BookType;
class BookController extends Controller
{
/**
* Lists all Book entities.
*
* @Route("/booklist", name="book")
* @Method("GET")
* @Template("AcmeDemoBundle:Book:list.html.twig")
*/
public function listAction()
{
$em = $this->container->get('doctrine')->getManager();
$books=$em->getRepository('AcmeDemoBundle:Book')->findAll();
return array(
'books' => $books,
);
}
/**
* Creates a new Book entity.
*
* @Route("/", name="book_create")
* @Method("POST")
* @Template("AcmeDemoBundle:Book:new.html.twig")
*/
public function createAction(Request $request)
{
$book = new Book();
$form = $this->createForm(new BookType(), $book);
$form->bind($request);
if ($form->isValid()) {
$em = $this->container->get('doctrine')->getManager();
$em->persist($book);
$em->flush();
return $this->redirect($this->generateUrl('book_show', array('id' => $book->getId())));
}
return array(
'form' => $form->createView(),
);
}
/**
* Displays a form to create a new Book entity.
*
* @Route("/new", name="book_new")
* @Method("GET")
* @Template()
*/
public function newAction()
{
$book = new Book();
$form = $this->createForm(new BookType(), $book);
return array(
'form' => $form->createView()
);
}
/**
* Finds and displays a Book entity.
*
* @Route("/{id}", name="book_show")
* @Method("GET")
* @Template()
*/
public function showAction($id)
{
$em = $this->container->get('doctrine')->getManager();
$book = $em->getRepository('AcmeDemoBundle:Book')->find($id);
if (!$book) {
throw $this->createNotFoundException('Unable to find Book entity.');
}
$deleteForm = $this->createDeleteForm($id);
return array(
'book' => $book,
'delete_form' => $deleteForm->createView(),
);
}
/**
* Displays a form to edit an existing Book entity.
*
* @Route("/{id}/edit", name="book_edit")
* @Method("GET")
* @Template()
*/
public function editAction($id)
{
$em = $this->container->get('doctrine')->getManager();
$book = $em->getRepository('AcmeDemoBundle:Book')->find($id);
if (!$book) {
throw $this->createNotFoundException('Unable to find Book entity.');
}
$editForm = $this->createForm(new BookType(), $book);
$deleteForm = $this->createDeleteForm($id);
return array(
'book' => $book,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
);
}
/**
* Edits an existing Book entity.
*
* @Route("/{id}", name="book_update")
* @Method("PUT")
* @Template("AcmeDemoBundle:Book:edit.html.twig")
*/
public function updateAction(Request $request, $id)
{
$em = $this->container->get('doctrine')->getManager();
$book = $em->getRepository('AcmeDemoBundle:Book')->find($id);
if (!$book) {
throw $this->createNotFoundException('Unable to find Book entity.');
}
$deleteForm = $this->createDeleteForm($id);
$editForm = $this->createForm(new BookType(), $book);
$editForm->bind($request);
if ($editForm->isValid()) {
$em->persist($book);
$em->flush();
return $this->redirect($this->generateUrl('book_edit', array('id' => $id)));
}
return array(
'book' => $book,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
);
}
/**
* Deletes a Book entity.
*
* @Route("/{id}", name="book_delete")
* @Method("DELETE")
*/
public function deleteAction(Request $request, $id)
{
$form = $this->createDeleteForm($id);
$form->bind($request);
if ($form->isValid()) {
$em = $this->container->get('doctrine')->getManager();
$book = $em->getRepository('AcmeDemoBundle:Book')->find($id);
if (!$book) {
throw $this->createNotFoundException('Unable to find Book entity.');
}
$em->remove($book);
$em->flush();
}
return $this->redirect($this->generateUrl('book'));
}
/**
* Creates a form to delete a Book entity by id.
*
* @param mixed $id The entity id
*
* @return \Symfony\Component\Form\Form The form
*/
private function createDeleteForm($id)
{
return $this->createFormBuilder(array('id' => $id))
->add('id', 'hidden')
->getForm()
;
}
}
<?php
namespace spec\Acme\DemoBundle\Controller;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Symfony\Component\DependencyInjection\Container;
use Doctrine\Bundle\DoctrineBundle\Registry;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\EntityManager;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Form\FormFactory;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormView;
use Symfony\Component\Routing\Router;
use \stdClass;
class BookControllerSpec extends ObjectBehavior {
function let(Container $container, Registry $doctrine, EntityRepository $repository, EntityManager $entityManager, Request $request, FormFactory $formFactory, FormBuilder $formBuilder, Form $form, FormView $formView, Router $router) {
$container->get('doctrine')->willReturn($doctrine);
$container->get('form.factory')->willReturn($formFactory);
$container->get('request')->willReturn($request);
$container->get('router')->willReturn($router);
$router->generate(Argument::cetera())->willReturn('url');
$formFactory->createBuilder(Argument::cetera())->willReturn($formBuilder);
$formBuilder->getForm(Argument::cetera())->willReturn($form);
$formFactory->create(Argument::cetera())->willReturn($form);
$form->createView()->willReturn($formView);
$doctrine->getManager()->willReturn($entityManager);
$entityManager->getRepository(Argument::any())->willReturn($repository);
$this->setContainer($container);
}
function it_is_initializable() {
$this->shouldHaveType('Acme\DemoBundle\Controller\BookController');
}
function it_is_of_type_container_aware() {
$this->shouldBeAnInstanceOf('Symfony\Component\DependencyInjection\ContainerAware');
}
function its_listAction_should_render_a_list_of_BookObjects($entityManager, $repository, stdClass $object) {
$entityManager->getRepository(Argument::exact('AcmeDemoBundle:Book'))->willReturn($repository);
$repository->findAll()->willReturn([$object]);
$this->listAction()->shouldReturn(['books' => [$object]]);
}
function its_createAction_should_save_the_BookObject_when_form_is_valid($request, $form, $formFactory, $entityManager) {
$classBook = Argument::exact('Acme\DemoBundle\Entity\Book')->getValue();
$book = new $classBook;
$classBookType = Argument::exact('Acme\DemoBundle\Form\BookType')->getValue();
$booktype = new $classBookType;
$formFactory->create($booktype, $book)->willReturn($form);
$form->bind($request)->willReturn($form);
$form->isValid()->willReturn(true);
$entityManager->persist($book)->shouldBeCalled();
$entityManager->flush()->shouldBeCalled();
$response = $this->createAction($request);
$response->shouldBeAnInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse');
}
function its_createAction_should_render_new_form_when_form_is_invalid($request, $form, $formView, $formFactory) {
$classBook = Argument::exact('Acme\DemoBundle\Entity\Book')->getValue();
$book = new $classBook;
$classBookType = Argument::exact('Acme\DemoBundle\Form\BookType')->getValue();
$booktype = new $classBookType;
$formFactory->create($booktype, $book)->willReturn($form);
$form->bind($request)->willReturn($form);
$form->isValid()->willReturn(false);
$form->createView()->willReturn($formView);
$this->createAction($request)->shouldReturn(
array(
'form' => $formView
)
);
}
function its_newAction_should_render_new_form($form, $formView, $formFactory) {
$classBook = Argument::exact('Acme\DemoBundle\Entity\Book')->getValue();
$book = new $classBook;
$classBookType = Argument::exact('Acme\DemoBundle\Form\BookType')->getValue();
$booktype = new $classBookType;
$formFactory->create($booktype, $book)->willReturn($form);
$form->createView()->willReturn($formView);
$this->newAction()->shouldReturn(
array(
'form' => $formView
)
);
}
function its_showAction_should_render_an_BookObject(stdClass $object, $entityManager, $repository, $form, $formView, $formBuilder, $formFactory) {
$entityManager->getRepository(Argument::exact('AcmeDemoBundle:Book'))->willReturn($repository);
$repository->find(1)->willReturn($object);
$formFactory->createBuilder(Argument::cetera())->willReturn($formBuilder);
$formBuilder->add('id', 'hidden')->willReturn($formBuilder);
$formBuilder->getForm()->willReturn($form);
$form->createView()->willReturn($formView);
$this->showAction(1)->shouldReturn(
array(
'book' => $object,
'delete_form' => $formView,
)
);
}
function its_showAction_should_throw_Exception_when_no_BookObject_found($entityManager, $repository) {
$entityManager->getRepository(Argument::exact('AcmeDemoBundle:Book'))->willReturn($repository);
$repository->find(2)->willReturn(null);
$this->shouldThrow('Symfony\Component\HttpKernel\Exception\NotFoundHttpException')->during('showAction', [2]);
}
function its_editAction_should_render_edit_form(stdClass $object, $entityManager, $repository, $form, $formView, $formBuilder, $formFactory) {
$entityManager->getRepository(Argument::exact('AcmeDemoBundle:Book'))->willReturn($repository);
$repository->find(1)->willReturn($object);
$formFactory->create(Argument::type('Acme\DemoBundle\Form\BookType'), $object)->willReturn($form);
$formFactory->createBuilder(1)->willReturn($formBuilder);
$formBuilder->add('id', 'hidden')->willReturn($formBuilder);
$formBuilder->getForm()->willReturn($form);
$form->createView()->willReturn($formView);
$form->createView()->willReturn($formView);
$this->editAction(1)->shouldReturn(
array(
'book' => $object,
'edit_form' => $formView,
'delete_form' => $formView
)
);
}
function its_editAction_should_throw_Exception_when_no_BookObject_found($entityManager, $repository) {
$entityManager->getRepository(Argument::exact('AcmeDemoBundle:Book'))->willReturn($repository);
$repository->find(2)->willReturn(null);
$this->shouldThrow('Symfony\Component\HttpKernel\Exception\NotFoundHttpException')->during('editAction', [2]);
}
function its_updateAction_should_save_the_BookObject_when_form_is_valid(stdClass $object, $repository, $request, $form, $formBuilder, $formFactory, $entityManager) {
$entityManager->getRepository(Argument::exact('AcmeDemoBundle:Book'))->willReturn($repository);
$repository->find(1)->willReturn($object);
$formFactory->createBuilder(1)->willReturn($formBuilder);
$formBuilder->add('id', 'hidden')->willReturn($formBuilder);
$formBuilder->getForm()->willReturn($form);
$form->bind($request)->willReturn($form);
$form->isValid()->willReturn(true);
$entityManager->persist($object)->shouldBecalled();
$entityManager->flush()->shouldBeCalled();
$response = $this->updateAction($request, 1);
$response->shouldBeAnInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse');
}
function its_updateAction_should_render_edit_form_when_form_is_invalid(stdClass $object, $entityManager, $repository, $request, $form, $formView, $formBuilder, $formFactory) {
$entityManager->getRepository(Argument::exact('AcmeDemoBundle:Book'))->willReturn($repository);
$repository->find(1)->willReturn($object);
$formFactory->create(Argument::type('Acme\DemoBundle\Form\BookType'), $object)->willReturn($form);
$formFactory->createBuilder(1)->willReturn($formBuilder);
$formBuilder->add('id', 'hidden')->willReturn($formBuilder);
$formBuilder->getForm()->willReturn($form);
$form->bind($request)->willReturn($form);
$form->isValid()->willReturn(false);
$form->createView()->willReturn($formView);
$form->createView()->willReturn($formView);
$this->updateAction($request, 1)->shouldReturn(
array(
'book' => $object,
'edit_form' => $formView,
'delete_form' => $formView
)
);
}
function its_updateAction_should_throw_Exception_when_no_BookObject_found($request) {
$this->shouldThrow('Symfony\Component\HttpKernel\Exception\NotFoundHttpException')->during('updateAction', array($request, [2]));
}
function its_deleteAction_should_delete_BookObject(stdClass $object, $repository, $request, $form, $formBuilder, $formFactory, $entityManager) {
$formFactory->createBuilder(1)->willReturn($formBuilder);
$formBuilder->add('id', 'hidden')->willReturn($formBuilder);
$formBuilder->getForm()->willReturn($form);
$form->bind($request)->willReturn($form);
$form->isValid()->willReturn(true);
$entityManager->getRepository(Argument::exact('AcmeDemoBundle:Book'))->willReturn($repository);
$repository->find(1)->willReturn($object);
$entityManager->remove($object)->shouldBeCalled();
$entityManager->flush()->shouldBeCalled();
$response = $this->deleteAction($request, 1);
$response->shouldBeAnInstanceOf('Symfony\Component\HttpFoundation\RedirectResponse');
}
function its_deleteAction_should_throw_Exception_when_no_BookObject_found($request, $entityManager, $repository, $form, $formBuilder, $formFactory) {
$formFactory->createBuilder(2)->willReturn($formBuilder);
$formBuilder->add('id', 'hidden')->willReturn($formBuilder);
$formBuilder->getForm()->willReturn($form);
$form->bind($request)->willReturn($form);
$form->isValid()->willReturn(true);
$entityManager->getRepository(Argument::exact('AcmeDemoBundle:Book'))->willReturn($repository);
$this->shouldThrow('Symfony\Component\HttpKernel\Exception\NotFoundHttpException')->during('deleteAction', array($request, [2]));
}
}
@silviuvoicu
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment