Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 829
Ashish Kumar Saxena Avatar asked Jan 18 '17 07:01

Ashish Kumar Saxena


People also ask

How do I run a PHPUnit test?

How to Run Tests in PHPUnit. You can run all the tests in a directory using the PHPUnit binary installed in your vendor folder. You can also run a single test by providing the path to the test file. You use the --verbose flag to get more information on the test status.

What is a PHPUnit test?

PHPUnit is a unit testing framework for the PHP programming language. It is an instance of the xUnit architecture for unit testing frameworks that originated with SUnit and became popular with JUnit. PHPUnit was created by Sebastian Bergmann and its development is hosted on GitHub.

Is PHPUnit a framework?

PHPUnit is a programmer-oriented testing framework for PHP. It is an instance of the xUnit architecture for unit testing frameworks. The currently supported versions are PHPUnit 9 and PHPUnit 8.


4 Answers

A little late, but for Symfony 5, you have the jsonRequest accessible via any WebTestCase

<?php
$this->client = static::createClient();

$this->client->jsonRequest('POST', '/myJsonEndpoint', [
    'key' => 'value'
]);
like image 92
Yann Chabot Avatar answered Oct 18 '22 04:10

Yann Chabot


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
    );
}
like image 43
Kamil Adryjanek Avatar answered Oct 18 '22 02:10

Kamil Adryjanek


Maybe it's a bit late... but it can help someone.

with this you can build a generic POST request and will be accepted by your controller. it's on Symfony 4.x using framework's HTTP client

use Symfony\Component\HttpFoundation\Request;

$request = new Request([], [], [], [], [], ['HTTP_CONTENT_TYPE' => 'application/json'], {"foo":"bar"}));
like image 26
Manuel Pirez Avatar answered Oct 18 '22 03:10

Manuel Pirez


CONTENT_TYPE vs HTTP_CONTENT_TYPE

TLDR;

For Symfony 5 use this:

use Symfony\Component\HttpFoundation\Request;

$request = new Request(
    $uri, $method, $parameters, $cookies, $files,
    $server=['CONTENT_TYPE' => 'application/json'], 
    $content={"foo":"bar"})
);

Careful, for Symfony 5.2, 5.3 (maybe earlier too) code below not working:

use Symfony\Component\HttpFoundation\Request;

$request = new Request(
    $uri, $method, $parameters, $cookies, $files,
    $server=['HTTP_CONTENT_TYPE' => 'application/json'], 
    $content={"foo":"bar"})
);

Why:

  1. if no CONTENT_TYPE is set then it added to $server there
  2. then it overrides HTTP_CONTENT_TYPE there
like image 36
Victor S. Avatar answered Oct 18 '22 02:10

Victor S.