Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel 5.4 testing route protected by $request->ajax(), how to make test ajax request?

I am trying to test a route that does something different in the controller whether or not the request is ajax or not.

public function someAction(Request $request)
{
    if($request->ajax()){
        // do something for ajax request
        return response()->json(['message'=>'Request is ajax']);
    }else{
        // do something else for normal requests
        return response()->json(['message'=>'Not ajax']);
    }
}

My test:

    public function testAjaxRoute()
{
    $url = '/the-route-to-controller-action';
    $response = $this->json('GET', $url);
    dd($response->dump());
}

When I run the test and just dump the response I get back 'Not ajax' - which makes sense I guess cause $this->json() is just expecting back a json response, not necessarily making an ajax request. But how can I correctly test this? I have been commenting the...

// if($request->ajax(){
    ...need to test this code
// }else{
    // ...
// }

every time I need to run the test on that portion of code. I'm looking for how to make an ajax request in my test case I guess...

like image 947
cmac Avatar asked Apr 17 '17 18:04

cmac


People also ask

What tests should I add to my Laravel application?

Laravel makes it super easy to add tests to your application. There may be times where you want to create a quick PHPUnit test to confirm your application URL's return a 200 request. I'm not suggesting that you only include tests that check all your route applications; however, this will be better than not including any tests at all.

What is unit testing in Laravel?

Unit tests are tests that focus on a very small, isolated portion of your code. In fact, most unit tests probably focus on a single method. Tests within your "Unit" test directory do not boot your Laravel application and therefore are unable to access your application's database or other framework services.

Where are Laravel routes stored in the application?

All Laravel routes are defined in your route files, which are located in the routes directory. These files are automatically loaded by your application's App\Providers\RouteServiceProvider.

Is it okay to use Laravel validation with jQuery?

It would be always greate if you use laravel validation for your web form in laravel project. we can use laravel validation very simply if we don't need to use jquery ajax. because laravel provide easy way to use validation without ajax. But if you want to use laravel validation with jquery then you can't do it easily.


2 Answers

In Laravel 5.4 tests this->post() and this->get() methods accept headers as the third parameter. Set HTTP_X-Requested-With to XMLHttpRequest

$this->post($url, $data, array('HTTP_X-Requested-With' => 'XMLHttpRequest'));

I added two methods to tests/TestCase.php to make easier.

<?php

namespace Tests;

use Illuminate\Foundation\Testing\TestCase as BaseTestCase;

abstract class TestCase extends BaseTestCase
{
    use CreatesApplication;

    /**
     * Make ajax POST request
     */
    protected function ajaxPost($uri, array $data = [])
    {
        return $this->post($uri, $data, array('HTTP_X-Requested-With' => 'XMLHttpRequest'));
    }

    /**
     * Make ajax GET request
     */
    protected function ajaxGet($uri, array $data = [])
    {
        return $this->get($uri, array('HTTP_X-Requested-With' => 'XMLHttpRequest'));
    }
}

Then from within any test, let's say tests/Feature/HomePageTest.php, I can just do:

public function testAjaxRoute()
{
  $url = '/ajax-route';
  $response = $this->ajaxGet($url)
        ->assertSuccessful()
        ->assertJson([
            'error' => FALSE,
            'message' => 'Some data'
        ]); 
}
like image 63
cmac Avatar answered Sep 30 '22 08:09

cmac


Try $response = \Request::create($url, 'GET', ["X-Requested-With" => "XMLHttpRequest"])->json();

like image 20
Dimitri Mostrey Avatar answered Sep 30 '22 09:09

Dimitri Mostrey