jeroenvanrensen's avatar

Laravel TDD - Test not working - Expected status code 403 but received 500

Hello everyone,

I'm new to Laravel and I'm following this tutorial on Laracasts where I'm making a forum with TDD.

I created a test, where a guest can't create a new forum thread. However, I'm getting a 500 status instead of a 403. Here's my test class:

<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
use App\Thread;

class CreateThreadTest extends TestCase
{
    use RefreshDatabase;

    /** @test */
    public function an_authenticated_user_can_create_new_forum_threads()
    {
        $this->actingAs(factory('App\User')->create());

        $thread = factory('App\Thread')->create();
        $this->post(route('threads.store'), $thread->toArray());

        $this->get(route('threads.show', $thread->id))
            ->assertSee($thread->title);
    }

    /** @test */
    public function a_guest_cannot_create_new_forum_threads()
    {
        $thread = factory('App\Thread')->make();

        $this->post(route('threads.store'), $thread->toArray())
            ->assertStatus(403);
    }
}

Here's my store function in my ThreadController:

public function store(Request $request)
{
    if(!Auth::check()) {
        abort(403);
    }
    
    $thread = Thread::create([
        'user_id' => auth()->user()->id,
        'title' => request('title'),
        'body' => request('body')
    ]);

    return redirect(route('threads.show', $thread));
}

And here's the error from CMD:

There was 1 failure:

1) Tests\Feature\CreateThreadTest::a_guest_cannot_create_new_forum_threads
Expected status code 403 but received 500.
Failed asserting that 403 is identical to 500.

I hope somebody can help, because I have no idea how to solve this.

If you need more information, please ask me.

Thanks for reading! Jeroen

0 likes
9 replies
tykus's avatar
tykus
Best Answer
Level 104

You can disable exception handling to see a full stack trace:

    /** @test */
    public function a_guest_cannot_create_new_forum_threads()
    {
	$this->withoutExceptionHandling(); // and read the stacktrace

        $thread = factory('App\Thread')->make();

        $this->post(route('threads.store'), $thread->toArray())
            ->assertStatus(403);
    }

Aside, the first test above is useless as it is currently written; to prove it, comment out the request line $this->post(/* etc */) and it will still pass. This is because you are asserting that the Thread you created using the factory exists, and not the Thread that should result from the request.

You need to fetch the thread that the request created for the test to be valid, e.g.

    public function an_authenticated_user_can_create_new_forum_threads()
    {
        $this->actingAs(factory('App\User')->create());

	// pre-action assert that there are no records:
	$this->assertEquals(0, Thread::count());

        $this->post(route('threads.store'), factory('App\Thread')->raw());

	// post-action assert that there are no records:
	$this->assertEquals(1, Thread::count());

        $this->get(route('threads.show', Thread::first()))
            ->assertSee($thread->title);
    }

alanholmes's avatar

Hi @jeroenvanrensen

Before your calls to $this->get or $this->post if you do $this->withoutExceptionHandling() you will get the actual errors rather than a 500 response, this should help you track down why you are getting the error

jeroenvanrensen's avatar

Hello,

I've changed my first test, and it returns green. I think now it's actually useful!

I've also turned on withoutExceptionHandling() and now I'm getting this error:

There was 1 error:

1) Tests\Feature\CreateThreadTest::a_guest_cannot_create_new_forum_threads
Symfony\Component\HttpKernel\Exception\HttpException

I've googled it but I couldn't find anything to do here. Do you know what to do?

Here's my new test class:

<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
use App\Thread;

class CreateThreadTest extends TestCase
{
    use RefreshDatabase;

    /** @test */
    public function an_authenticated_user_can_create_new_forum_threads()
    {
        $this->withoutExceptionHandling();

        $user = factory('App\User')->create();
        $this->be($user);

        $this->assertEquals(0, Thread::count());

        $thread = factory('App\Thread')->raw();
        $this->post(route('threads.store'), $thread);

        $this->assertEquals(1, Thread::count());
        
        $thread = Thread::first();
        $this->get(route('threads.show', $thread->id))
            ->assertSee($thread->title);
    }

    /** @test */
    public function a_guest_cannot_create_new_forum_threads()
    {
        $this->withoutExceptionHandling();

        $thread = factory('App\Thread')->raw();

        $this->post(route('threads.store'), $thread);
            // ->assertStatus(403);
    }
}
tykus's avatar

I've also turned on withoutExceptionHandling() and now I'm getting this error:

What does the reset of the stacktrace say; or at least the next lines?

jeroenvanrensen's avatar

This is the full error message:

C:\wamp64\www\laravel\forum>php vendor/phpunit/phpunit/phpunit --filter CreateThreadTest
PHPUnit 8.5.5 by Sebastian Bergmann and contributors.

.E                                                                  2 / 2 (100%)

Time: 1.95 seconds, Memory: 26.00 MB

There was 1 error:

1) Tests\Feature\CreateThreadTest::a_guest_cannot_create_new_forum_threads
Symfony\Component\HttpKernel\Exception\HttpException:

C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Foundation\Application.php:1067
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Foundation\helpers.php:44
C:\wamp64\www\laravel\forum\app\Http\Controllers\ThreadController.php:29
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Routing\Controller.php:54
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Routing\ControllerDispatcher.php:45
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Routing\Route.php:239
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Routing\Route.php:196
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Routing\Router.php:685
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:128
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Routing\Middleware\SubstituteBindings.php:41
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:167
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken.php:76
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:167
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\View\Middleware\ShareErrorsFromSession.php:49
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:167
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Session\Middleware\StartSession.php:116
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Session\Middleware\StartSession.php:62
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:167
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse.php:37
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:167
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Cookie\Middleware\EncryptCookies.php:66
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:167
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:103
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Routing\Router.php:687
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Routing\Router.php:662
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Routing\Router.php:628
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Routing\Router.php:617
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php:165
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:128
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\TransformsRequest.php:21
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:167
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\TransformsRequest.php:21
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:167
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\ValidatePostSize.php:27
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:167
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode.php:63
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:167
C:\wamp64\www\laravel\forum\vendor\fruitcake\laravel-cors\src\HandleCors.php:37
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:167
C:\wamp64\www\laravel\forum\vendor\fideloper\proxy\src\TrustProxies.php:57
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:167
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:103
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php:140
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php:109
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\MakesHttpRequests.php:468
C:\wamp64\www\laravel\forum\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\MakesHttpRequests.php:286
C:\wamp64\www\laravel\forum\tests\Feature\CreateThreadTest.php:41

ERRORS!
Tests: 2, Assertions: 3, Errors: 1.
tykus's avatar

Looks like the problem is with the abort helper (if that is Controller line 29?)

jeroenvanrensen's avatar

Hi Tykus,

Here's the store function on my Controller, the abort function is line 29. If I comment out the Auth::check if loop, I got this error message, so I think it has something to do with it, but I've got no idea what.

ErrorException: Trying to get property 'id' of non-object
public function store(Request $request)
{
    if(!Auth::check()) {
        abort(403);
    }
    
    $thread = Thread::create([
        'user_id' => auth()->user()->id,
        'title' => request('title'),
        'body' => request('body')
    ]);

    return redirect(route('threads.show', $thread));
}

Do you know what to do?

tykus's avatar

Well that error is understandable given that auth()->user() will be null because you are not signed in (as your test enforces).

Re-reading the stacktrace above now, that HttpException makes sense, it is your 403! Remove the $this->withoutExceptionHandling() line again, so that Laravel can handle the exception. If you are getting a 500 again, the problem must be somewhere in the Exception handling logic; you would need to check the log file instead storage/logs/laravel.log usually.

jeroenvanrensen's avatar

Hello Tykus,

Thanks for your answer, but suddenly it's working!

Also thanks for everyone's previous answers!

Please or to participate in this conversation.