Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony2 Functional test: Passing form data directly

I am using phpunit to run functional tests but I am having a problem with a few of the forms. The problem is that phpunit is not aware of JS, and I have a form with a dynamically populated select box that needs jQuery.

So I need to pass the form data directly. The 'book' gives the following example:

// Directly submit a form (but using the Crawler is easier!)
$client->request('POST', '/submit', array('name' => 'Fabien'));

When I used this example the controller didn't receive any of the form data. Intially I saw that passing the array key 'name' wasn't correct in my situation as I needed the form name which was 'timesheet' in my code. So I tried something like:

$client->request('POST', '/timesheet/create', array('timesheet[project]' => '100'));

But this still didn't work. In the controller I tried to understand what was happening and what if anything was being received:

$postData = $request->request->get('timesheet');
$project = $postData['project'];

This didn't work and $project remained empty. However if I used the following code I got the value:

$project = $request->request->get('timesheet[project]');

But clearly that's not what I want. Atleast though I can see that there is some POST data. My last attempt was to try the following in the test method:

$this->crawler = $this->client->request('POST', '/timesheet/create/', array('timesheet' => array(project => '100'));

So I am trying to pass a 'timesheet' array as the first element of the request parameter array. But with this I get the error:

Symfony\Component\Form\Exception\UnexpectedTypeException: Expected argument of type "array", "string" given (uncaught exception) at /mnt/hgfs/pmt/src/vendor/symfony/src/Symfony/Component/Form/Form.php line 489

I would be very happy if someone can expand on what's in the 'book' about how I am supposed to get this working.

Form bind in controller:

    if ($request->getMethod() == 'POST') {
        $form->bindRequest($request);

        if ($form->isValid()) {
            $postData = $request->request->get('timesheet');
            $project = $postData['project'];                             

            $timesheetmanager = $this->get('wlp_pmt.timesheet_db_access');
            $timesheetmanager->editTimesheet($timesheet);                                               
            return $this->redirect($this->generateUrl('timesheet_list'));
        }
    }
like image 919
DanF7 Avatar asked Jan 25 '12 15:01

DanF7


1 Answers

If you are wanting to know how to inject arrays of POST data using the test client...

In your test method, do something like

$crawler = $client->request('POST', '/foo', array(
    'animal_sounds' => array(
        'cow'  => 'moo',
        'duck' => 'quack'
    )
); // This would encode to '/foo?animal_sounds%5Bcow%5D=moo&animal_sounds%5Bduck%5D=quack'

$this->assertTrue( ... );

In the controller, you would access your params like this:

$data = $request->request->get('animal_sounds');
$cowNoise = $data['cow'];
$duckNoise = $data['duck'];

Or you could just use the forms API if the test method was injecting valid form data...

like image 56
Paul Tregoing Avatar answered Oct 13 '22 09:10

Paul Tregoing