nchankov's avatar

findOrFail and creating a test

Hello, I am trying to test a url which return 404 generated from faindOrFail() method;

Here is the code sample:

in routes.php

Route::get(
    'user/test',
    function(){
        $user = App\User::findOrFail(1111); //non existent
    }
);

And I have simple testcase with the following code: UserTest.php

class UserTest extends TestCase
{
   public function testUser(){
        $this->visit('user/test')
            ->assertResponseStatus(404);
    }
}

I also have a file 404.blade.php in resources/views/errors, but I don't think it matters.

So I would expect that the test to pass, but instead of this I got

1) UserTest::testUser
A request to [http://localhost/user/test] failed. Received status code [404].
...
Caused by
exception 'Illuminate\Database\Eloquent\ModelNotFoundException' with message 'No query results for model [App\User].' in /var/www/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:209

If I see the url as user I see the 404 contents and I am quite ok with them, but the test fails.

So, could you give me any hints how to test such errors?

0 likes
4 replies
jekinney's avatar

How do you want the error handled?

The status code is as maybe you hinted to, not the issue as its generic. But I set handle the exception as more of an error.

nchankov's avatar

In this instance I don't want any further handling - just displaying the 404 page is good enough. The example above is not correct, because I am checking the code with:

App\User::where('active', true)->findOrFail($id);

So, when they user disable his profile, I should display 404 page (profile is missing) and if he enables it it will be displayed as it should and I wanted to write a test when the user switched off and on this field.

primordial's avatar

You can add an annotation to your test stating that you expect an exception to be thrown

    /**
     * @expectedException InvalidArgumentException
     */
    public function testException()
    {
        ...
    }
1 like
nchankov's avatar
nchankov
OP
Best Answer
Level 1

I've checked the class which causes the exception:

/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/InteractsWithPages.php

and I've seen that it trow an \Illuminate\Foundation\Testing\HttpException And I just catch the exception wth the following code:

public function testUser()
    {
        try {
            $this->visit('/user/test');
        } catch (\Illuminate\Foundation\Testing\HttpException $e) {
            $this->assertResponseStatus(404);
        }
    }

Hope this will help some one

Please or to participate in this conversation.