Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I have a fairly ugly controller method I would like to refactor / extract. I can only test this in a integration type test which kind of signals a code smell.

The method processes the form and needs to do one of 5 things, depending on which button was pressed

  1. if submitted and valid (button 1) => update some values on the entity and re-render the form
  2. if submitted and valid (button 2) => perform another controller action that shows a pdf print of the entity
  3. if submitted and valid (button 3) => save entity and redirect
  4. if not submitted or not valid => render form (plus errors)

In code it looks kind of like this

protected function processForm(Request $request, MyEntity $entity)
{
    $form = $this->createForm(new MyEntityType, $entity);

    if ($form->handleRequest($request)->isValid()) {

        $alteredEntity = SomeClass:performStuffOnEntity($entity);

        if ($form->get('button1')->isClicked()) {
            $form = $this->createForm(
                new MyEntityType, $alteredEntity
            );
        }
        else if ($form->get('button2')->isClicked()) {
            return $this->pdfPreview($alteredEntity);
        }
        else if ($form->get('button3')->isClicked()) {
            return $this->persistAndRedirectToEntity(
                $alteredEntity
            );
        }
    }

    return $this->render(
        'MyBundle:MyEntity:new.html.twig', array(
            'form' => $form->createView(),
    ));
}

Actually there are two buttons like button1, I left one out for brevity of the example.

Idea 1: I have tried to extract this into a EntityFormWizard of some sort but this ended up as a cluttered Object with too many dependencies (Router, Templating, Form) which was also a pain to test.

Idea 2: Using FormEvents I wanted to extract at least the altering of the entity depending on which button was pressed into a FormEventListener, but the only place where I can alter the Entity is the FormEvents::PRE_SET_DATA event, but in there I have problems figuring out which button was clicked.

So the question: Do I have to live with my integration test for this behavior or is there a way to extract it and test it with a unit test?

share|improve this question

migrated from stackoverflow.com Nov 21 '13 at 22:57

This question came from our site for professional and enthusiast programmers.

    
In every case, controller has a large number of dependencies for unit testing(request, routing, templates, forms, db, etc). But it is not difficult to understand that he do and your controller not looking fat. I dont think it makes sense to split it into independent modules to simplify testing, but reduce code read-ablitity. Unit testing has great value with bussiness logic, but functional testing is great for testing stuff like controller responses imo. Anyway its to hard to mock all dependencies in controller for pure unit tests. –  forgottenbas Nov 21 '13 at 8:41

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.