Search code examples
ajaxsymfonytestingphpunitsymfony-3.2

Symfony how to test an AJAX request


In my project I have a piece of my form that sends an AJAX request:

 $.ajax({
     url: '/bio_control/sample',
     type: 'POST',
     dataType: 'json',
     data: {sample_number: $(input_field).val()}, 
 });

Which activates the following controller method:

/**
 * @Route("/bio_control/sample", name="get_bio_control_sample")
 */
public function getBioControlSampleAction(Request $request)
{

    $sample_number = $request->request->get('sample_number');

    /**
     * Additional logic not shown for brevity.
     */

    $user_id = $user->getId();
    $response = array("code" => 100, "success" => true, "sample_number" => $sample_number, "sample_data" => $sample[0], "new_user" => false, "user_id" => $user_id);

    return new JsonResponse($response);
}

I'd like to be able to test this request in isolation, but I'm unsure how to write the request object.

So far my first attempt:

public function testGetBioControlSample()
    {
        $helper = $this->helper;
        $client = $this->makeClient();
        $crawler = $client->request('POST', "/bio_control/sample", array(), array('sample_number' => 67655), array(
            'CONTENT_TYPE' => 'application/json',
            'HTTP_X-Requested-With' => 'XMLHttpRequest'
        ));
        $this->assertStatusCode(200, $client);
    }

Fails because it appears to be submitting the form (I get an error related to a form field completely unrelated to the AJAX request being blank).

Can anyone demonstrate how to correctly write such a test?


Solution

  • Does this URL need authentication?

    I like to use LiipFunctionalTestBundle for my functional tests and they usually looks like this:

    <?php
    
    declare(strict_types=1);
    
    namespace Tests\Your\Namespace;
    
    use Liip\FunctionalTestBundle\Test\WebTestCase;
    
    class PostResourceActionTest extends WebTestCase
    {
        public function testShouldReturnResponseWithOkStatusCode(): void
        {
            $credentials = [
                'username' => 'user',
                'password' => 'pass'
            ];
            $client = $this->makeClient($credentials);
    
            $payload = ['foo' => 'bar'];
            $client->request(
                'POST',
                '/the/url/',
                $payload,
                [],
                ['HTTP_Content-Type' => 'application/json']
            );
    
            $this->assertStatusCode(200, $client);
        }
    }
    

    Maybe the error you are getting is the login form asking for authentication?