使用 JSON 请求正文测试 Laravel 控制器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14171816/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Testing laravel controllers with JSON request body
提问by Reidsy
I am trying to write a phpunit test for a Laravel controller which expects post requests with a body in JSON format.
我正在尝试为 Laravel 控制器编写一个 phpunit 测试,该控制器期望使用 JSON 格式的正文发布请求。
A simplified version of the controller:
控制器的简化版本:
class Account_Controller extends Base_Controller
{
public $restful = true;
public function post_login()
{
$credentials = Input::json();
return json_encode(array(
'email' => $credentials->email,
'session' => 'random_session_key'
));
}
}
Currently I have a test method which is correctly sending the data as urlencoded form data, but I cannot work out how to send the data as JSON.
目前我有一个测试方法,它可以正确地将数据作为 urlencoded 表单数据发送,但我无法弄清楚如何将数据作为 JSON 发送。
My test method (I used the github gist herewhen writing the test)
我的测试方法(我在写测试的时候用了这里的github gist )
class AccountControllerTest extends PHPUnit_Framework_TestCase {
public function testLogin()
{
$post_data = array(
'email' => '[email protected]',
'password' => 'example_password'
);
Request::foundation()->server->set('REQUEST_METHOD', 'POST');
Request::foundation()->request->add($post_data);
$response = Controller::call('account@login', $post_data);
//check the $response
}
}
I am using angularjs on the frontend and by default, requests sent to the server are in JSON format. I would prefer not to change this to send a urlencoded form.
我在前端使用 angularjs,默认情况下,发送到服务器的请求采用 JSON 格式。我不想改变它来发送一个 urlencoded 表单。
Does anyone know how I could write a test method which provides the controller with a JSON encoded body?
有谁知道我如何编写一个为控制器提供 JSON 编码主体的测试方法?
采纳答案by Naveen
There is a lot easier way of doing this. You can simply set Input::$json property to the object you want to send as post parameter. See Sample code below
有很多更简单的方法可以做到这一点。您可以简单地将 Input::$json 属性设置为要作为 post 参数发送的对象。请参阅下面的示例代码
$data = array(
'name' => 'sample name',
'email' => '[email protected]',
);
Input::$json = (object)$data;
Request::setMethod('POST');
$response = Controller::call('client@create');
$this->assertNotNull($response);
$this->assertEquals(200, $response->status());
I hope this helps you with your test cases
我希望这对您的测试用例有所帮助
Update : The original article is available here http://forums.laravel.io/viewtopic.php?id=2521
更新:原始文章可在此处获得http://forums.laravel.io/viewtopic.php?id=2521
回答by eoinoc
In Laravel 5, the call()
method has changed:
在 Laravel 5 中,call()
方法发生了变化:
$this->call(
'PUT',
$url,
[],
[],
[],
['CONTENT_TYPE' => 'application/json'],
json_encode($data_array)
);
I think that Symphony's request()
method is being called:
http://symfony.com/doc/current/book/testing.html
我认为 Symphony 的request()
方法正在被调用:http:
//symfony.com/doc/current/book/testing.html
回答by carbontwelve
This is how I go about doing this in Laravel4
这就是我在 Laravel4 中这样做的方式
// Now Up-vote something with id 53
$this->client->request('POST', '/api/1.0/something/53/rating', array('rating' => 1) );
// I hope we always get a 200 OK
$this->assertTrue($this->client->getResponse()->isOk());
// Get the response and decode it
$jsonResponse = $this->client->getResponse()->getContent();
$responseData = json_decode($jsonResponse);
$responseData
will be a PHP object equal to the json response and will allow you to then test the response :)
$responseData
将是一个等于 json 响应的 PHP 对象,并允许您测试响应:)
回答by Aaron Pollock
Here's what worked for me.
这对我有用。
$postData = array('foo' => 'bar');
$postRequest = $this->action('POST', 'MyController@myaction', array(), array(), array(), array(), json_encode($postData));
$this->assertTrue($this->client->getResponse()->isOk());
That seventh argument to $this->action
is content
. See docs at http://laravel.com/api/source-class-Illuminate.Foundation.Testing.TestCase.html#_action
的第七个参数$this->action
是content
。请参阅http://laravel.com/api/source-class-Illuminate.Foundation.Testing.TestCase.html#_action 上的文档
回答by jimbo2087
As of Laravel 5.1 there is a much easier way to test JSON controllers via PHPunit. Simply pass an array with the data and it'll get encoded automatically.
从 Laravel 5.1 开始,有一种更简单的方法可以通过 PHPunit 测试 JSON 控制器。只需传递一个包含数据的数组,它就会自动编码。
public function testBasicExample()
{
$this->post('/user', ['name' => 'Sally'])
->seeJson([
'created' => true,
]);
}
From the docs: http://laravel.com/docs/5.1/testing#testing-json-apis
回答by Laurence
A simple solution would be to use CURL - which will then also allow you to capture the 'response' from the server.
一个简单的解决方案是使用 CURL - 然后它也允许您从服务器捕获“响应”。
class AccountControllerTest extends PHPUnit_Framework_TestCase
{
public function testLogin()
{
$url = "account/login";
$post_data = array(
'email' => '[email protected]',
'password' => 'example_password'
);
$content = json_encode($post_data);
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-type: application/json"));
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $content);
$json_response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
$response = json_decode($json_response, true);
// Do some $this->Assert() stuff here on the $status
}
}
CURL will actually simulate the raw HTTP post with JSON - so you know you are truly testing your functionality;
CURL 实际上会用 JSON 模拟原始的 HTTP 帖子——所以你知道你真的在测试你的功能;