jsonphpunitsymfonywebtest

How to pass JSON in POST method with PhpUnit Testing?


I am using symfony 3.0 with phpUnit framework 3.7.18

Unit Test file. abcControllerTest.php

namespace AbcBundle\Tests\Controller;


use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\HttpFoundation\Response;

class AbcControllerTest extends WebTestCase {


    public function testWithParams() {
        $Params = array("params" => array("page_no" => 5));
        $expectedData = $this->listData($Params);

        print_r($expectedData);
    }

    private function listData($Params) {
        $client = static::createClient();        
        $server = array('HTTP_CONTENT_TYPE' => 'application/json', 'HTTP_ACCEPT' => 'application/json');
        $crawler = $client->request('POST', $GLOBALS['host'] . '/abc/list', $Params,array(), $server);
        $response = $client->getResponse();
        $this->assertSame('text/html; charset=UTF-8', $response->headers->get('Content-Type'));
        $expectedData = json_decode($response->getContent());
        return $expectedData;
    }

}

Action : abc/list

abcController.php

public function listAction(Request $request) {      
        $Params = json_decode($request->getContent(), true);
}

Code is working fine but not given expected result.Since i am trying to pass json parameter from my phpunit file abcControllerTest.php to controller abcController.php file. Anyone can suggest me how can i achieve the same things.


Solution

  • I prefer using GuzzleHttp for external requests :

    use GuzzleHttp\Client;
    
    $client = new Client();
    
    $response = $client->post($url, [
        GuzzleHttp\RequestOptions::JSON => ['title' => 'title', 'body' => 'body']
    ]);
    

    Note: GuzzleHttp should be installed with e.g. using composer.

    But you can always use client bundled with Symfony:

    public function testJsonPostPageAction()
    {
        $this->client = static::createClient();
        $this->client->request(
            'POST', 
            '/api/v1/pages.json',  
            array(),
            array(),
            array('CONTENT_TYPE' => 'application/json'),
            '[{"title":"title1","body":"body1"},{"title":"title2","body":"body2"}]'
        );
        $this->assertJsonResponse($this->client->getResponse(), 201, false);
    }
    
    protected function assertJsonResponse($response, $statusCode = 200)
    {
        $this->assertEquals(
            $statusCode, $response->getStatusCode(),
            $response->getContent()
        );
        $this->assertTrue(
            $response->headers->contains('Content-Type', 'application/json'),
            $response->headers
        );
    }