如何通过 PhpUnit 测试在 POST 方法中传递 JSON?
How to pass JSON in POST method with PhpUnit Testing?
我正在使用带有 phpUnit 框架 3.7.18 的 symfony 3.0
单元测试文件。
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;
}
}
操作:abc/list
abcController.php
public function listAction(Request $request) {
$Params = json_decode($request->getContent(), true);
}
代码工作正常但没有给出预期 result.Since 我正在尝试将我的 phpunit 文件 abcControllerTest.php 中的 json 参数传递给控制器abcController.php 文件。
任何人都可以建议我如何实现相同的目标。
我更喜欢对外部请求使用 GuzzleHttp
:
use GuzzleHttp\Client;
$client = new Client();
$response = $client->post($url, [
GuzzleHttp\RequestOptions::JSON => ['title' => 'title', 'body' => 'body']
]);
注意:GuzzleHttp
应该与例如使用作曲家。
但您始终可以使用与 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
);
}
也许有点晚了...但它可以帮助某人。
有了这个,您可以构建一个通用的 POST 请求,并将被您的控制器接受。它在 Symfony 4.x 上使用框架的 HTTP 客户端
use Symfony\Component\HttpFoundation\Request;
$request = new Request([], [], [], [], [], ['HTTP_CONTENT_TYPE' => 'application/json'], {"foo":"bar"}));
CONTENT_TYPE 与 HTTP_CONTENT_TYPE
TLDR;
对于 Symfony 5 使用这个:
use Symfony\Component\HttpFoundation\Request;
$request = new Request(
$uri, $method, $parameters, $cookies, $files,
$server=['CONTENT_TYPE' => 'application/json'],
$content={"foo":"bar"})
);
小心,对于 Symfony 5.2,5.3(可能更早)下面的代码不起作用:
use Symfony\Component\HttpFoundation\Request;
$request = new Request(
$uri, $method, $parameters, $cookies, $files,
$server=['HTTP_CONTENT_TYPE' => 'application/json'],
$content={"foo":"bar"})
);
为什么:
有点晚了,但是对于 Symfony 5,您可以通过任何 WebTestCase
访问 jsonRequest
<?php
$this->client = static::createClient();
$this->client->jsonRequest('POST', '/myJsonEndpoint', [
'key' => 'value'
]);
我正在使用带有 phpUnit 框架 3.7.18 的 symfony 3.0
单元测试文件。 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;
}
}
操作:abc/list
abcController.php
public function listAction(Request $request) {
$Params = json_decode($request->getContent(), true);
}
代码工作正常但没有给出预期 result.Since 我正在尝试将我的 phpunit 文件 abcControllerTest.php 中的 json 参数传递给控制器abcController.php 文件。 任何人都可以建议我如何实现相同的目标。
我更喜欢对外部请求使用 GuzzleHttp
:
use GuzzleHttp\Client;
$client = new Client();
$response = $client->post($url, [
GuzzleHttp\RequestOptions::JSON => ['title' => 'title', 'body' => 'body']
]);
注意:GuzzleHttp
应该与例如使用作曲家。
但您始终可以使用与 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
);
}
也许有点晚了...但它可以帮助某人。
有了这个,您可以构建一个通用的 POST 请求,并将被您的控制器接受。它在 Symfony 4.x 上使用框架的 HTTP 客户端
use Symfony\Component\HttpFoundation\Request;
$request = new Request([], [], [], [], [], ['HTTP_CONTENT_TYPE' => 'application/json'], {"foo":"bar"}));
CONTENT_TYPE 与 HTTP_CONTENT_TYPE
TLDR;
对于 Symfony 5 使用这个:
use Symfony\Component\HttpFoundation\Request;
$request = new Request(
$uri, $method, $parameters, $cookies, $files,
$server=['CONTENT_TYPE' => 'application/json'],
$content={"foo":"bar"})
);
小心,对于 Symfony 5.2,5.3(可能更早)下面的代码不起作用:
use Symfony\Component\HttpFoundation\Request;
$request = new Request(
$uri, $method, $parameters, $cookies, $files,
$server=['HTTP_CONTENT_TYPE' => 'application/json'],
$content={"foo":"bar"})
);
为什么:
有点晚了,但是对于 Symfony 5,您可以通过任何 WebTestCase
jsonRequest
<?php
$this->client = static::createClient();
$this->client->jsonRequest('POST', '/myJsonEndpoint', [
'key' => 'value'
]);