Laravel testing. Is possible to use multiple calls in same test?

Viewed 1891

I have this test:

public function test_user_can_access_the_application_page(  
{
        $user=[
            'email'=>'user@user.com',
            'password'=>'user1234',
        ];

        $response=$this->call('POST','/login',$user);
        $this->assertAuthenticated();
        $response->assertStatus(302)
            ->assertRedirect('/dashboard')
            ->assertLocation('/dashboard');
        $response=$this->call('GET','/application/index');
        $response->assertLocation('/application/index');
}

After I log in, it directs me to the dashboard ok until now, but if I want to access the other page after that, I cant. This error comes up.

Expected :'http://mock.test/application/index'

Actual :'http://mock.test'

Aren't multiple calls allowed in the same test, or is another way to access other pages after login? (Note: It's not possible to use factories for the actingAs so I need to login).

4 Answers

I guess you will need to call the function as an user, since you can only access it logged in. Laravel provides the actingAs() method for such cases.

https://laravel.com/docs/7.x/http-tests#session-and-authentication

You can create a random User who has the permission to log into your app or take a seeded one and call the function acting as the chosen User.

$response=$this->actingAs($user)->call('GET','/application/index');

If you call it without actingAs(), your middleware will redirect you back to the login or home screen (what you defined in the LoginController ).

In my opinion this test case should have its own testing method. I recommend using a test method per route or per use case. It makes your tests clearly arranged and easy to understand.

If you want to be authenticated, the easiest way is to have PHPUnit simulate authentication using the actingAs() method.

This method makes the user authenticated, so you wouldn't want to test the login method with it. You should write your login tests separate from testing the other pages.

To answer your question, yes you can make multiple requests in the same test, but in this case linking the login test to the 'application/index' page likely does not make much sense.

public function test_the_user_can_login()
{
    $user = [
        'email'=>'user@user.com',
        'password'=>'user1234',
    ];

    $response = $this->call('POST','/login',$user);
    $this->assertAuthenticated();
    $response->assertStatus(302)
             ->assertRedirect('/dashboard')
             ->assertLocation('/dashboard');
}

public function test_user_can_access_the_application_page()
{
    $user = User::where($email, "user@user.com")->first();

    $response = $this->actingAs($user)
                     ->call('GET','/application/index');

    $response->assertLocation('/application/index');
}

I experienced that in laravel 8 I use comment @test and involved second test!!! I mean if you use two function for test you must us @test that php artisan test, test both of them.

Related