myregistration's avatar

Which assert test for when missing parameter in route?

How should I test for a missing parameter in route request when using TestCase? I thought it would be assertBadRequest(), but that didn't work. Is it something along the lines of assertThrows(UrlGenerationException)? Thanks!

0 likes
15 replies
LaryAI's avatar
Level 58

To test for a missing parameter in a route request using Laravel's TestCase, you can use the assertSessionHasErrors method. Here's an example:

$response = $this->get('/example-route');
$response->assertSessionHasErrors('parameter_name');

This will assert that the response has a session error for the specified parameter name. If the parameter is missing, the test will pass. If the parameter is present, the test will fail.

Note that you'll need to replace example-route and parameter_name with the actual route and parameter name you're testing.

tykus's avatar

A missing parameter; such as a URL segment, or query parameter???

myregistration's avatar

@tykus A missing segment. The uuid missing from the following route:

Route::get('/invitation/{invitation:uuid}/accept', App\Http\Livewire\Invitation\Accept::class)->name('invitation.accept');

tykus's avatar

@myregistration well that'll be a 404, because the requested URL will be /invitation//accept right?

$this->get('/invitation//accept')
    ->assertStatus(404);
myregistration's avatar

@tykus That doesn't seem to work. I get a UrlGenerationException in the test. The browser request does return 404.

myregistration's avatar

@tykus I tried your suggestion, but didn't work. Here's the function

public function guest_can_not_access_accept_invitation_without_uuid(): void
{
    $this->withoutExceptionHandling()->get(route('invitation.accept'))
            ->assertNotFound();
}
tykus's avatar

@myregistration ah, I see now what you're doing... the problem is not with a Request, it is the route helper cannot generate the URL in the first place because the required parameter is missing! You could prove the Request will fail by passing an empty string for the UUID:

public function guest_can_not_access_accept_invitation_without_uuid(): void
{
    $this->get(route('invitation.accept', ''))
            ->assertNotFound();
}

However, this is still going to fail if you use the route helper in your application and the UUID is empty (null); the question I would have is why/how would the UUID be empty?

myregistration's avatar

@tykus I'm new to testing and trying to cover most scenarios. I'll try passing a bogus uuid. Thanks!

tykus's avatar

No worries, mark the thread closed please

myregistration's avatar

@tykus These tests both worked

/** @test */
public function guest_can_not_access_accept_invitation_without_uuid(): void
{
    $this->get(route('invitation.accept', ''))
        ->assertNotFound();
}

/** @test */
public function guest_can_not_access_accept_invitation_with_invalid_uuid(): void
{
    $this->get(route('invitation.accept', '1234567890'))
        ->assertNotFound();
}
tykus's avatar
tykus
Best Answer
Level 104

@myregistration right, but for different reasons... (i) there is no URL registered matching the one generated by the route helper and (ii) there is a matching route, but Route Model binding finds no Invitation record matching the given UUID

myregistration's avatar

@tykus I'm a little confused on the parameter for the route. I can pass a model instance of an invitation, but if I were to pass an array should I pass the key as "invitation" or "uuid"? I tried both and "invitation" worked, but "uuid" failed so I assume "invitation" and uuid is just telling it which field to use to find it :)

Route::get('/invitation/{invitation:uuid}/accept', App\Http\Livewire\Invitation\Accept::class)->name('invitation.accept');

/** @test */
public function guest_can_not_access_accept_invitation_with_invalid_uuid(): void
{
    $this->get(route('invitation.accept', ['invitation' => '1234567890']))
        ->assertNotFound();
}
tykus's avatar

@myregistration the wildcard segment is named invitation, so that is the array key that should be used.

1 like

Please or to participate in this conversation.