MrAndre
MrAndre

Reputation: 1017

Laravel phpunit testing get with parameters

I am writing some tests for my controllers but one of my tests doesn't work. It's supossed to search and get the results back to the page. But it's actually redirecting to the home page. Here is my code:

use DatabaseMigrations;
protected $user;
public function setUp()
{
    parent::setUp();

    $this->seed();

    $this->user = factory(User::class)->create(['role_id' => 3]);
}

/** @test */
public function test_manage_search_user()
{
    $response = $this->followingRedirects()->actingAs($this->user)->get('/manage/users/search', [
        'choices' => 'username',
        'search' => $this->user->username,
    ]);

    $response->assertViewIs('manage.users');
    $response->assertSuccessful();
    $response->assertSee($this->user->email);
}

The URL you should get to make it work look like this:

http://localhost/manage/users/search?choices=username&search=Test

I checked again and it looks like it's not given in the parameters with the get request. How can I fix this?

Upvotes: 35

Views: 42636

Answers (10)

Misha Voloshchuk
Misha Voloshchuk

Reputation: 11

The accepted answer did not work anymore on a Laravel 11.33.2 installation (API error: no-auth), but this did:

$this->get(url()->query('/path/to/api', [
    'key' => 'value',
    'search' => 'username',
]));

Here's the Laravel URL Generation docs.

Upvotes: 1

Nicekiwi
Nicekiwi

Reputation: 4807

Late to the party, but I've been using this in my TestCase helper trait for Laravel 10.

public function getJsonWithParams($uri, $headers = [], $params = []): TestResponse
{
    return $this->getJson($uri . '?' . http_build_query($params), $headers);
}

Not amazing for discovery, but it works.

Here because I forgot I created it, and came looking for ideas.

Upvotes: 0

hkodavid
hkodavid

Reputation: 13

Add a helper function:

if (!function_exists('extend_url_with_query_data')) {
    function extend_url_with_query_data(string $url, array $queryData): string
    {
        if ($queryData == []) {
            return $url;
        }

        $glue = mb_strpos($url, '?') === false ? '?' : '&';

        $queryString = http_build_query($queryData);

        return "{$url}{$glue}{$queryString}";
    }
}

Usage:

$queryData = [
    'works' => true,
];

$this->get(
    extend_url_with_query_data('/api/v1/example', $queryData)
);

Upvotes: 1

digid
digid

Reputation: 11

This worked for me simply pass the parameter as part of the url as follows:


$response = $this->get('api/endpoint?parameter1='.$this->dynamicParam);

Upvotes: 1

Aslam-Ep
Aslam-Ep

Reputation: 141

In order to send parameters with GET requests.

  1. If you use the route() method then you can pass the data as the second parameter.

    $response = $this->get(route('route_name', ['key' => value]));

  2. If you using URL directly, you could use like this

    $response = $this->get('url?' . Arr::query(['key' => value]));

Do whatever you want to do with $response.

Upvotes: 5

Ben
Ben

Reputation: 1660

You could use the request helper to merge in http get parameters as such:

    /** @var \Illuminate\Http\Request $request */
    $request = request();
    $request->merge([
        'choices' => 'username',
        'search' => 'Test'
    ]);

Upvotes: 2

shxfee
shxfee

Reputation: 5306

You can use the route helper to build a url with query string. in your case i would do something like this. Assuming the route name is manage.users.search

$route = route('manage.users.search', [
    'choices'=> 'username',
    'search' => $this->user->username,
]);

$response = $this->followingRedirects()
    ->actingAs($this->user)
    ->get($route);

Upvotes: 12

Hyder B.
Hyder B.

Reputation: 12186

I'm using Laravel 5.X (more precisely 5.6), you can pass custom parameters using:

 $response = $this->json('GET',  '/url/endpoint',['params'=>'value']);

Upvotes: 23

MathieuAuclair
MathieuAuclair

Reputation: 1327

I had the same issue trying to test GET Requests, you actually can't pass parameter with the $this->get('uri', [header]) but you can by using $this->call, if you check in MakesHttpRequests.php you can see that this->get() is actually using call method.

By adding an array to get method, you are changing the request headers, this is why you are not getting your parameters.

public function get($uri, array $headers = [])
{
    $server = $this->transformHeadersToServerVars($headers);

    return $this->call('GET', $uri, [], [], [], $server);
}

public function call($method, $uri, $parameters = [], $cookies = [], $files = [], $server = [], $content = null)
{
    $kernel = $this->app->make(HttpKernel::class);

    $files = array_merge($files, $this->extractFilesFromDataArray($parameters));

    $symfonyRequest = SymfonyRequest::create(
        $this->prepareUrlForRequest($uri), $method, $parameters,
        $cookies, $files, array_replace($this->serverVariables, $server), $content
    );

    $response = $kernel->handle(
        $request = Request::createFromBase($symfonyRequest)
    );

    if ($this->followRedirects) {
        $response = $this->followRedirects($response);
    }

    $kernel->terminate($request, $response);

    return $this->createTestResponse($response);
}

So if you want to test a GET Request you will have to do this:

$request = $this->call('GET', '/myController', ["test"=>"test"]);

In your controller you should be able to get theses parameters like so:

public function myController(Request $request)
{
    $requestContent = $request->all();
    $parameter = $requestContent['test'];
}

Upvotes: 34

Raza Mehdi
Raza Mehdi

Reputation: 941

I would do it like this:

$this->actingAs($this->user);

$response = $this->get('/manage/users/search', [
    'choices' => 'username',
    'search' => $this->user->username,
]);

$response->assertViewIs('manage.users');
$response->assertSuccessful();
$response->assertSee($this->user->email);

Upvotes: -2

Related Questions