更新见下文
我的控制器区分ajax和其他请求(使用Request::ajax()
作为条件)。这工作得很好,但我想知道是否有一种单元测试控制器处理请求的方法。测试应该如何?
可能是这样的东西,但它不起作用......
<?php
class UsersControllerTest extends TestCase
{
public function testShowUser()
{
$userId = 1;
$response = $this->call('GET', '/users/2/routes', array(), array(), array(
'HTTP_CUSTOM' => array(
'X-Requested-With' => 'XMLHttpRequest'
)
));
}
}
更新
我找到了一个解决方案。也许。由于我对测试Request类的正确功能不感兴趣(很可能Laravel,Symfony等提供的所有本机类已经进行了足够的单元测试),最好的方法是模拟它的ajax方法。像这样:
public function testShowUser()
{
$mocked = Request::shouldReceive('ajax')
->once()
->andReturn(true);
$controller = new UsersCustomRoutesController;
$controller->show(2,2);
}
因为在使用Request
类的call
方法时使用了真正的Testcase
类而不是它的模拟替换,我必须实例化在指定路由时调用的方法手工输入。但我认为这是可以的,因为我只想控制Request::ajax()
条件中的表达式在此测试中按预期工作。
答案 0 :(得分:14)
您需要在实际标头前加上HTTP_,不需要使用HTTP_CUSTOM:
$server = array('HTTP_X-Requested-With' => 'XMLHttpRequest');
$this->call('get', '/ajax-route', array(), array(), $server);
替代语法看起来好一点IMO:
$this->client->setServerParameter('HTTP_X-Requested-With', 'XMLHttpRequest');
$this->call('get', '/ajax-route');
以下是JSON标头(Request::isJson()
和Request::wantsJson()
)的一些类似代码示例:
$this->client->setServerParameter('HTTP_CONTENT_TYPE', 'application/json');
$this->call('get', '/is-json');
$this->client->setServerParameter('HTTP_ACCEPT', 'application/json');
$this->call('get', '/wants-json');
这是一个有用的辅助方法,可以放在TestCase中:
protected function prepareAjaxJsonRequest()
{
$this->client->setServerParameter('HTTP_X-Requested-With', 'XMLHttpRequest');
$this->client->setServerParameter('HTTP_CONTENT_TYPE', 'application/json');
$this->client->setServerParameter('HTTP_ACCEPT', 'application/json');
}
答案 1 :(得分:5)
这是Laravel 5.2的解决方案。
$this->json('get', '/users/2/routes');
就这么简单。
最初,json
方法适用于以下标题:
'CONTENT_LENGTH' => mb_strlen($content, '8bit'),
'CONTENT_TYPE' => 'application/json',
'Accept' => 'application/json',
答案 2 :(得分:3)
在Laravel 5中:
$this->get('/users/2/routes', ['HTTP_X-Requested-With' => 'XMLHttpRequest']);
然后你可以链接正常的断言:
$this->get('/users/2/routes', ['HTTP_X-Requested-With' => 'XMLHttpRequest'])
->seeJsonStructure([
'*' => ['id', 'name'],
]);
答案 3 :(得分:2)
$server = array('HTTP_X-Requested-With' => 'XMLHttpRequest');
$request = new \Illuminate\Http\Request($query = array(),$request = array(), $attributes = array(), $cookies = array(), $files = array(), $server , $content = null);
答案 4 :(得分:1)
作为已有答案的补充,出于澄清的目的,您可以将那些帮助方法添加到 TestCase
<?php
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
use CreatesApplication;
// ...
/**
* Make ajax POST request
*
* @param string $uri
* @param array $data
* @return \Illuminate\Foundation\Testing\TestResponse
*/
public function ajaxPost($uri, array $data = [])
{
return $this->post($uri, $data, ['HTTP_X-Requested-With' => 'XMLHttpRequest']);
}
/**
* Make ajax GET request
*
* @param string $uri
* @return \Illuminate\Foundation\Testing\TestResponse
*/
public function ajaxGet($uri)
{
return $this->get($uri, ['HTTP_X-Requested-With' => 'XMLHttpRequest']);
}
}
<?php
class ExampleTest extends TestCase
{
/**
* A basic functional test example.
*
* @return void
*/
public function testBasicExample()
{
$response = $this->ajaxPost('/user', ['name' => 'Sally']);
$response
->assertStatus(201)
->assertJson([
'created' => true,
]);
}
}