10

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.

4 Answers 4

12

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 ); } 
Sign up to request clarification or add additional context in comments.

1 Comment

GuzzleHttp is for making real HTTP request, while Symfony's client simulates a browser and makes requests to a Kernel object. The latter has a lot more APIs to simplify unit testing. It also removes the need to have a web server to run the unit test.
9

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' ]); 

Comments

1

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

Comments

1

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.