How to simulate xmlHttpRequests in a laravel test sheet?

See updates below.

My controllers distinguish between ajax and other requests (using Request::ajax() as a condition). This works fine, but I'm wondering if there is a way to modularly check controllers that handle requests. What should the test look like? Maybe something like this, but it does not work ...

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

Update

I have found a solution. May be. Since I'm not interested in testing the correct functionality of the Request class (it is very likely that all the native classes provided by Laravel, Symfony, etc., are already sufficient for unit testing), the best way would be to mock his ajax method. Like this:

  public function testShowUser() { $mocked = Request::shouldReceive('ajax') ->once() ->andReturn(true); $controller = new UsersCustomRoutesController; $controller->show(2,2); } 

Since the real Request class, and not its fake substitute, is used when using the call method of the Testcase class, I had to create an instance of the method that is called when the specified route is entered manually. But I think this is normal, because I just want to control that the expressions inside the Request::ajax() condition work as expected with this test.

+6
source share
5 answers

You need the prefix of the actual HTTP_ header, no need to use HTTP_CUSTOM:

 $server = array('HTTP_X-Requested-With' => 'XMLHttpRequest'); $this->call('get', '/ajax-route', array(), array(), $server); 

Alternative syntax that looks a little better IMO:

 $this->client->setServerParameter('HTTP_X-Requested-With', 'XMLHttpRequest'); $this->call('get', '/ajax-route'); 

Here are some sample code for the JSON headers ( Request::isJson() and 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'); 

Here is a useful helper method that you can add to your test system:

 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'); } 
+15
source

Here is the solution for Laravel 5.2.

 $this->json('get', '/users/2/routes'); 

It's simple.


Intenally, the json method is applied to the following headers:

 'CONTENT_LENGTH' => mb_strlen($content, '8bit'), 'CONTENT_TYPE' => 'application/json', 'Accept' => 'application/json', 
+6
source

In Laravel 5:

 $this->get('/users/2/routes', ['HTTP_X-Requested-With' => 'XMLHttpRequest']); 

Then you can bind the normal statements:

 $this->get('/users/2/routes', ['HTTP_X-Requested-With' => 'XMLHttpRequest']) ->seeJsonStructure([ '*' => ['id', 'name'], ]); 
+3
source
 $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); 
+2
source

Laravel 5.X

In addition to pre-existing answers and for clarity, you can add these helper methods to your 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']); } } 

Using
 <?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, ]); } } 
0
source

Source: https://habr.com/ru/post/958468/


All Articles