How to pass JSON in POST method with PhpUnit Testing? How to pass JSON in POST method with PhpUnit Testing? symfony symfony

How to pass JSON in POST method with PhpUnit Testing?


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    );}


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"}));


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