laravelmastery
SnippetsArticlesSeriesNews

Test-driven Laravel · Lesson 1 of 3

Test-driven Laravel · Lesson 1

Acting as a user

The shape of a testTesting

You have called actingAs() since the first lesson. This lesson is what that call does, and what it does not do. actingAs() sets the user for the guard the route uses, which for these invoices is the default web guard. The same user stays signed in for the next request in that test.

Video

01 Sign in before the request

Chain it. The redirect and the saved team id both depend on who was signed in.

PHP
it('assigns the invoice to the signed-in team', function () {
    $user = User::factory()->create();

    $this->actingAs($user)
        ->post('/invoices', [
            'number' => 'INV-1042',
            'issued_on' => '2026-10-22',
        ])
        ->assertRedirect();

    $this->assertDatabaseHas('invoices', [
        'number' => 'INV-1042',
        'team_id' => $user->current_team_id,
    ]);
});

A guest is the absence of actingAs(), not a user with an empty name. The guest test is separate, and it asserts a redirect to login rather than a saved invoice.

actingAs($user) does not run the login controller. It does not check the password. The password check belongs in a test of the login form, not in every invoice test.

02 A guest test is the one that omits actingAs()

Do not build a user and then forget to sign them in if the test is about a member. Do not build a user at all if the test is about a guest. The guest request is the same post, without the chain.

PHP
it('does not store an invoice for a guest', function () {
    $this->post('/invoices', [
        'number' => 'INV-1042',
        'issued_on' => '2026-10-22',
    ])->assertRedirect('/login');

    $this->assertDatabaseCount('invoices', 0);
});

actingAs($user, 'web') is the explicit guard when a route uses a guard other than the default. These invoice routes use web. Passing the guard on every invoice test only repeats the default. A test of an API token uses the sanctum guard, and that test is not this one. The session guard is what the browser uses, so it is the guard these feature tests sign in with.

Recap

You can sign a user in for the web guard without going through the login form.

  • actingAs() does not check the password. A password test belongs on the login form.
  • A guest test omits actingAs(). It does not use an empty user.
  • Pass the guard name only when the route is not on the default web guard.

Check yourself · 3 questions

Question 1 of 3Every invoice test posts the login form first. What are you repeating?

actingAs() signs the member in and does not check the password. Next, the request that member is allowed to make.

← PreviousFactories that read like the domain

On this page

  • Sign in before the request
  • A guest test is the one that omits actingAs()
  • Recap
  • Check yourself

Test-driven Laravel

  • 1 Overview

The shape of a test

  • 2 What a feature test is for
  • 3 Arrange, act, assert
  • 4 Refreshing the database
  • 5 Factories that read like the domain
  • 6 Acting as a user

The paths that matter

  • 7 HTTP tests for happy paths
  • 8 Validation errors
  • 9 Authorisation

Edges and judgement

  • 10 Faking the mail
  • 11 Faking the queue
  • 12 Faking storage and HTTP
  • 13 Freezing time
  • 14 Datasets
  • 15 What not to test

Test-driven Laravel

Lessons

  1. 01Overview

The shape of a test

  1. 02What a feature test is for
  2. 03Arrange, act, assert
  3. 04Refreshing the database
  4. 05Factories that read like the domain
  5. 06Acting as a user

The paths that matter

  1. 07HTTP tests for happy paths
  2. 08Validation errors
  3. 09Authorisation

Edges and judgement

  1. 10Faking the mail
  2. 11Faking the queue
  3. 12Faking storage and HTTP
  4. 13Freezing time
  5. 14Datasets
  6. 15What not to test

Get the Friday email

One snippet and the week’s Laravel news, in your inbox every Friday morning. Unsubscribe whenever you like.

laravelmastery

Practical Laravel learning for working developers, made in the UK.

Learn

  • Snippets
  • Articles
  • Series

Stay current

  • News
  • Friday email
  • RSS feed

Company

  • About
  • Privacy
  • Terms
© 2026 Laravel Mastery. Independent and not affiliated with Laravel Holdings Inc.Designed and built by Half Shell Studios

We remember the videos you watch, where you left off, and which series lessons you mark as read, against this connection’s address. Nothing is stored until you agree.