> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# HTTP-tests

> Uitleg over het simuleren van requests, assertions, authenticatietests en tests voor bestandsuploads met de HTTP-testfunctionaliteit van Laravel

## Introductie

Laravel biedt een rijke API om HTTP-requests te simuleren en responses te verifiëren.
Je kunt requests aan je applicatie binnen tests nabootsen zonder een echte HTTP-server op te zetten.

<CodeGroup>
  ```php Pest theme={null}
  <?php

  test('de applicatie geeft een succesvolle response terug', function () {
      $response = $this->get('/');

      $response->assertStatus(200);
  });
  ```

  ```php PHPUnit theme={null}
  <?php

  namespace Tests\Feature;

  use Tests\TestCase;

  class ExampleTest extends TestCase
  {
      public function test_the_application_returns_a_successful_response(): void
      {
          $response = $this->get('/');

          $response->assertStatus(200);
      }
  }
  ```
</CodeGroup>

De methode `get()` stuurt een `GET`-request naar de applicatie en `assertStatus()` verifieert de HTTP-statuscode van de teruggekregen response.

<Info>
  Tijdens het uitvoeren van tests wordt de CSRF-middleware automatisch uitgeschakeld. Je hoeft die in tests niet expliciet uit te schakelen.
</Info>

## Requests maken

Binnen tests kun je requests versturen met de methoden `get`, `post`, `put`, `patch` en `delete`.
Deze methoden versturen geen echt netwerkrequest, maar simuleren het binnen de applicatie.
De retourwaarde is een instantie van `Illuminate\Testing\TestResponse`, die diverse assertion-methoden biedt.

<CodeGroup>
  ```php Pest theme={null}
  <?php

  test('een basisrequest', function () {
      $response = $this->get('/');

      $response->assertStatus(200);
  });
  ```

  ```php PHPUnit theme={null}
  <?php

  namespace Tests\Feature;

  use Tests\TestCase;

  class ExampleTest extends TestCase
  {
      public function test_a_basic_request(): void
      {
          $response = $this->get('/');

          $response->assertStatus(200);
      }
  }
  ```
</CodeGroup>

<Warning>
  Het is aan te raden om binnen één testmethode in principe maar één request te versturen. Meerdere requests binnen dezelfde test uitvoeren kan onverwacht gedrag veroorzaken.
</Warning>

### Requestheaders aanpassen

Met de methode `withHeaders()` pas je de headers van het request aan.

<CodeGroup>
  ```php Pest theme={null}
  <?php

  test('request met headers', function () {
      $response = $this->withHeaders([
          'X-Header' => 'Value',
      ])->post('/user', ['name' => 'Sally']);

      $response->assertStatus(201);
  });
  ```

  ```php PHPUnit theme={null}
  <?php

  namespace Tests\Feature;

  use Tests\TestCase;

  class ExampleTest extends TestCase
  {
      public function test_interacting_with_headers(): void
      {
          $response = $this->withHeaders([
              'X-Header' => 'Value',
          ])->post('/user', ['name' => 'Sally']);

          $response->assertStatus(201);
      }
  }
  ```
</CodeGroup>

### Cookies

Met de methoden `withCookie()` of `withCookies()` stel je cookiewaarden in vóór het request.

<CodeGroup>
  ```php Pest theme={null}
  <?php

  test('request met cookies', function () {
      $response = $this->withCookie('color', 'blue')->get('/');

      $response = $this->withCookies([
          'color' => 'blue',
          'name'  => 'Taylor',
      ])->get('/');
  });
  ```

  ```php PHPUnit theme={null}
  <?php

  namespace Tests\Feature;

  use Tests\TestCase;

  class ExampleTest extends TestCase
  {
      public function test_interacting_with_cookies(): void
      {
          $response = $this->withCookie('color', 'blue')->get('/');

          $response = $this->withCookies([
              'color' => 'blue',
              'name'  => 'Taylor',
          ])->get('/');
      }
  }
  ```
</CodeGroup>

### Sessie en authenticatie

Met de methode `withSession()` stel je sessiedata in vóór het request.

<CodeGroup>
  ```php Pest theme={null}
  <?php

  test('request met sessie', function () {
      $response = $this->withSession(['banned' => false])->get('/');
  });
  ```

  ```php PHPUnit theme={null}
  <?php

  namespace Tests\Feature;

  use Tests\TestCase;

  class ExampleTest extends TestCase
  {
      public function test_interacting_with_the_session(): void
      {
          $response = $this->withSession(['banned' => false])->get('/');
      }
  }
  ```
</CodeGroup>

Met de methode `actingAs()` verstuur je requests als geauthenticeerde gebruiker. Je gebruikt dit in combinatie met modelfactory's.

<CodeGroup>
  ```php Pest theme={null}
  <?php

  use App\Models\User;

  test('een actie die authenticatie vereist', function () {
      $user = User::factory()->create();

      $response = $this->actingAs($user)
          ->withSession(['banned' => false])
          ->get('/');
  });
  ```

  ```php PHPUnit theme={null}
  <?php

  namespace Tests\Feature;

  use App\Models\User;
  use Tests\TestCase;

  class ExampleTest extends TestCase
  {
      public function test_an_action_that_requires_authentication(): void
      {
          $user = User::factory()->create();

          $response = $this->actingAs($user)
              ->withSession(['banned' => false])
              ->get('/');
      }
  }
  ```
</CodeGroup>

Geef je de guardnaam door als tweede argument van `actingAs()`, dan wordt met die guard geauthenticeerd. Voor de duur van de test wordt die guard de standaard.

```php theme={null}
$this->actingAs($user, 'web');
```

Wil je een request versturen zonder authenticatie, gebruik dan `actingAsGuest()`.

```php theme={null}
$this->actingAsGuest();
```

### Responses debuggen

Wil je tijdens een test de inhoud van de response bekijken, gebruik dan de methoden `dump`, `dumpHeaders` en `dumpSession`.

<CodeGroup>
  ```php Pest theme={null}
  <?php

  test('response debuggen', function () {
      $response = $this->get('/');

      $response->dump();
      $response->dumpHeaders();
      $response->dumpSession();
  });
  ```

  ```php PHPUnit theme={null}
  <?php

  namespace Tests\Feature;

  use Tests\TestCase;

  class ExampleTest extends TestCase
  {
      public function test_debug_response(): void
      {
          $response = $this->get('/');

          $response->dump();
          $response->dumpHeaders();
          $response->dumpSession();
      }
  }
  ```
</CodeGroup>

Wil je de uitvoering stoppen, gebruik dan de methoden `dd`, `ddHeaders`, `ddBody`, `ddJson` en `ddSession`.

```php theme={null}
$response->dd();
$response->ddHeaders();
$response->ddBody();
$response->ddJson();
$response->ddSession();
```

### Excepties testen

Om te testen dat een specifieke exceptie wordt gegooid, gebruik je de `Exceptions`-facade.

<CodeGroup>
  ```php Pest theme={null}
  <?php

  use App\Exceptions\InvalidOrderException;
  use Illuminate\Support\Facades\Exceptions;

  test('exceptie wordt gegooid', function () {
      Exceptions::fake();

      $response = $this->get('/order/1');

      // Controleren dat de exceptie is gegooid
      Exceptions::assertReported(InvalidOrderException::class);

      // De inhoud van de exceptie controleren
      Exceptions::assertReported(function (InvalidOrderException $e) {
          return $e->getMessage() === 'The order was invalid.';
      });
  });
  ```

  ```php PHPUnit theme={null}
  <?php

  namespace Tests\Feature;

  use App\Exceptions\InvalidOrderException;
  use Illuminate\Support\Facades\Exceptions;
  use Tests\TestCase;

  class ExampleTest extends TestCase
  {
      public function test_exception_is_thrown(): void
      {
          Exceptions::fake();

          $response = $this->get('/');

          Exceptions::assertReported(InvalidOrderException::class);

          Exceptions::assertReported(function (InvalidOrderException $e) {
              return $e->getMessage() === 'The order was invalid.';
          });
      }
  }
  ```
</CodeGroup>

Om te controleren dat een exceptie niet is gegooid, gebruik je `assertNotReported` of `assertNothingReported`.

```php theme={null}
Exceptions::assertNotReported(InvalidOrderException::class);

Exceptions::assertNothingReported();
```

Wil je een request versturen met uitgeschakelde exceptieafhandeling, gebruik dan `withoutExceptionHandling()`.

```php theme={null}
$response = $this->withoutExceptionHandling()->get('/');
```

Om te testen of code in een closure een exceptie gooit, gebruik je `assertThrows()`.

```php theme={null}
$this->assertThrows(
    fn () => (new ProcessOrder)->execute(),
    OrderInvalid::class
);

// De inhoud van de exceptie controleren
$this->assertThrows(
    fn () => (new ProcessOrder)->execute(),
    fn (OrderInvalid $e) => $e->orderId() === 123
);
```

Om te controleren dat er geen exceptie wordt gegooid, gebruik je `assertDoesntThrow()`.

```php theme={null}
$this->assertDoesntThrow(fn () => (new ProcessOrder)->execute());
```

## JSON-API's testen

Laravel biedt veel helpers voor het testen van JSON-API's.
Met de methoden `json`, `getJson`, `postJson`, `putJson`, `patchJson`, `deleteJson` en `optionsJson` verstuur je JSON-requests.

<CodeGroup>
  ```php Pest theme={null}
  <?php

  test('een API-request versturen', function () {
      $response = $this->postJson('/api/user', ['name' => 'Sally']);

      $response
          ->assertStatus(201)
          ->assertJson([
              'created' => true,
          ]);
  });
  ```

  ```php PHPUnit theme={null}
  <?php

  namespace Tests\Feature;

  use Tests\TestCase;

  class ExampleTest extends TestCase
  {
      public function test_making_an_api_request(): void
      {
          $response = $this->postJson('/api/user', ['name' => 'Sally']);

          $response
              ->assertStatus(201)
              ->assertJson([
                  'created' => true,
              ]);
      }
  }
  ```
</CodeGroup>

Op de data van een JSON-response heb je toegang als arrayvariabele.

<CodeGroup>
  ```php Pest theme={null}
  expect($response['created'])->toBeTrue();
  ```

  ```php PHPUnit theme={null}
  $this->assertTrue($response['created']);
  ```
</CodeGroup>

<Info>
  `assertJson()` zet de response om naar een array en verifieert of de opgegeven array in de JSON-response voorkomt. Ook als de JSON andere properties bevat, slaagt de test zolang het opgegeven fragment aanwezig is.
</Info>

### Assertions op exacte overeenkomst

Met `assertExactJson()` verifieer je dat de teruggegeven JSON **exact overeenkomt** met de opgegeven array.

<CodeGroup>
  ```php Pest theme={null}
  <?php

  test('JSON-assertion op exacte overeenkomst', function () {
      $response = $this->postJson('/user', ['name' => 'Sally']);

      $response
          ->assertStatus(201)
          ->assertExactJson([
              'created' => true,
          ]);
  });
  ```

  ```php PHPUnit theme={null}
  <?php

  namespace Tests\Feature;

  use Tests\TestCase;

  class ExampleTest extends TestCase
  {
      public function test_asserting_an_exact_json_match(): void
      {
          $response = $this->postJson('/user', ['name' => 'Sally']);

          $response
              ->assertStatus(201)
              ->assertExactJson([
                  'created' => true,
              ]);
      }
  }
  ```
</CodeGroup>

### Assertions op JSON-paden

Met `assertJsonPath()` verifieer je de data op een opgegeven pad.

<CodeGroup>
  ```php Pest theme={null}
  <?php

  test('assertion op een JSON-pad', function () {
      $response = $this->postJson('/user', ['name' => 'Sally']);

      $response
          ->assertStatus(201)
          ->assertJsonPath('team.owner.name', 'Darian');
  });
  ```

  ```php PHPUnit theme={null}
  <?php

  namespace Tests\Feature;

  use Tests\TestCase;

  class ExampleTest extends TestCase
  {
      public function test_asserting_a_json_paths_value(): void
      {
          $response = $this->postJson('/user', ['name' => 'Sally']);

          $response
              ->assertStatus(201)
              ->assertJsonPath('team.owner.name', 'Darian');
      }
  }
  ```
</CodeGroup>

Je kunt ook een closure doorgeven voor flexibelere verificatie.

```php theme={null}
$response->assertJsonPath('team.owner.name', fn (string $name) => strlen($name) >= 3);
```

### Fluente JSON-tests

Geef je een closure door aan `assertJson()`, dan kun je met een `AssertableJson`-instantie fluent assertions schrijven.

<CodeGroup>
  ```php Pest theme={null}
  use Illuminate\Testing\Fluent\AssertableJson;

  test('fluente JSON-test', function () {
      $response = $this->getJson('/users/1');

      $response
          ->assertJson(fn (AssertableJson $json) =>
              $json->where('id', 1)
                  ->where('name', 'Victoria Faith')
                  ->where('email', fn (string $email) => str($email)->is('victoria@gmail.com'))
                  ->whereNot('status', 'pending')
                  ->missing('password')
                  ->etc()
          );
  });
  ```

  ```php PHPUnit theme={null}
  use Illuminate\Testing\Fluent\AssertableJson;

  public function test_fluent_json(): void
  {
      $response = $this->getJson('/users/1');

      $response
          ->assertJson(fn (AssertableJson $json) =>
              $json->where('id', 1)
                  ->where('name', 'Victoria Faith')
                  ->where('email', fn (string $email) => str($email)->is('victoria@gmail.com'))
                  ->whereNot('status', 'pending')
                  ->missing('password')
                  ->etc()
          );
  }
  ```
</CodeGroup>

<Tip>
  De methode `etc()` staat toe dat er properties bestaan waarop geen assertion is gedaan. Gebruik je `etc()` niet, dan faalt de test wanneer er properties bestaan waar je geen assertion op doet. Zo voorkom je dat je onbedoeld gevoelige informatie in de response opneemt.
</Tip>

Om de aan- of afwezigheid van attributen te controleren gebruik je `has()` en `missing()`.

```php theme={null}
$response->assertJson(fn (AssertableJson $json) =>
    $json->has('data')
        ->missing('message')
);
```

Om meerdere attributen tegelijk te controleren gebruik je `hasAll()` en `missingAll()`.

```php theme={null}
$response->assertJson(fn (AssertableJson $json) =>
    $json->hasAll(['status', 'data'])
        ->missingAll(['message', 'code'])
);
```

#### Assertions op JSON-collecties

Geeft een route een JSON-response met meerdere items terug, dan kun je met de methode `has()` het aantal items en de inhoud van de collectie verifiëren.

```php theme={null}
$response
    ->assertJson(fn (AssertableJson $json) =>
        $json->has(3)
            ->first(fn (AssertableJson $json) =>
                $json->where('id', 1)
                    ->where('name', 'Victoria Faith')
                    ->missing('password')
                    ->etc()
            )
    );
```

Om dezelfde assertions op alle items toe te passen gebruik je `each()`.

```php theme={null}
$response
    ->assertJson(fn (AssertableJson $json) =>
        $json->has(3)
            ->each(fn (AssertableJson $json) =>
                $json->whereType('id', 'integer')
                    ->whereType('name', 'string')
                    ->whereType('email', 'string')
                    ->missing('password')
                    ->etc()
            )
    );
```

#### Assertions op JSON-types

Met `whereType()` en `whereAllType()` verifieer je het type van properties.

```php theme={null}
$response->assertJson(fn (AssertableJson $json) =>
    $json->whereType('id', 'integer')
        ->whereAllType([
            'users.0.name' => 'string',
            'meta' => 'array'
        ])
);
```

Met het `|`-teken kun je ook meerdere types opgeven. De assertion slaagt zodra één van de types overeenkomt.

```php theme={null}
$response->assertJson(fn (AssertableJson $json) =>
    $json->whereType('name', 'string|null')
        ->whereType('id', ['string', 'integer'])
);
```

De beschikbare types zijn `string`, `integer`, `double`, `boolean`, `array` en `null`.

## Authenticatietests

Met `actingAs()` verstuur je requests als geauthenticeerde gebruiker.

<CodeGroup>
  ```php Pest theme={null}
  <?php

  use App\Models\User;
  use Illuminate\Foundation\Testing\RefreshDatabase;

  uses(RefreshDatabase::class);

  test('geauthenticeerde gebruiker kan het dashboard bekijken', function () {
      $user = User::factory()->create();

      $response = $this->actingAs($user)->get('/dashboard');

      $response->assertStatus(200);
  });

  test('niet-geauthenticeerde gebruiker wordt geredirect', function () {
      $response = $this->get('/dashboard');

      $response->assertRedirect('/login');
  });
  ```

  ```php PHPUnit theme={null}
  <?php

  namespace Tests\Feature;

  use App\Models\User;
  use Illuminate\Foundation\Testing\RefreshDatabase;
  use Tests\TestCase;

  class DashboardTest extends TestCase
  {
      use RefreshDatabase;

      public function test_authenticated_users_can_view_the_dashboard(): void
      {
          $user = User::factory()->create();

          $response = $this->actingAs($user)->get('/dashboard');

          $response->assertStatus(200);
      }

      public function test_unauthenticated_users_are_redirected(): void
      {
          $response = $this->get('/dashboard');

          $response->assertRedirect('/login');
      }
  }
  ```
</CodeGroup>

Om met een specifieke guard te authenticeren geef je de guardnaam op als tweede argument.

```php theme={null}
$this->actingAs($user, 'api');
```

### Voorbeeld: de registratieflow testen

Een voorbeeld waarin het echte registratie-endpoint wordt getest.

<CodeGroup>
  ```php Pest theme={null}
  <?php

  use App\Models\User;
  use Illuminate\Foundation\Testing\RefreshDatabase;

  uses(RefreshDatabase::class);

  test('gebruiker kan zich registreren', function () {
      $response = $this->post('/register', [
          'name'                  => 'Test User',
          'email'                 => 'test@example.com',
          'password'              => 'password',
          'password_confirmation' => 'password',
      ]);

      $response->assertRedirect('/dashboard');
      $this->assertDatabaseHas('users', ['email' => 'test@example.com']);
  });

  test('registreren met een dubbel e-mailadres is niet mogelijk', function () {
      User::factory()->create(['email' => 'test@example.com']);

      $response = $this->post('/register', [
          'name'                  => 'Test User',
          'email'                 => 'test@example.com',
          'password'              => 'password',
          'password_confirmation' => 'password',
      ]);

      $response->assertSessionHasErrors('email');
  });
  ```

  ```php PHPUnit theme={null}
  <?php

  namespace Tests\Feature;

  use App\Models\User;
  use Illuminate\Foundation\Testing\RefreshDatabase;
  use Tests\TestCase;

  class RegistrationTest extends TestCase
  {
      use RefreshDatabase;

      public function test_user_can_register(): void
      {
          $response = $this->post('/register', [
              'name'                  => 'Test User',
              'email'                 => 'test@example.com',
              'password'              => 'password',
              'password_confirmation' => 'password',
          ]);

          $response->assertRedirect('/dashboard');
          $this->assertDatabaseHas('users', ['email' => 'test@example.com']);
      }

      public function test_duplicate_email_cannot_register(): void
      {
          User::factory()->create(['email' => 'test@example.com']);

          $response = $this->post('/register', [
              'name'                  => 'Test User',
              'email'                 => 'test@example.com',
              'password'              => 'password',
              'password_confirmation' => 'password',
          ]);

          $response->assertSessionHasErrors('email');
      }
  }
  ```
</CodeGroup>

## Sessies testen

Met `withSession()` stel je vooraf sessiedata in en verstuur je vervolgens het request.
Met `assertSessionHas()` verifieer je of een waarde in de sessie bestaat.

<CodeGroup>
  ```php Pest theme={null}
  <?php

  test('sessiewaarde verifiëren', function () {
      $response = $this->withSession(['locale' => 'ja'])->get('/');

      $response->assertSessionHas('locale', 'ja');
  });
  ```

  ```php PHPUnit theme={null}
  <?php

  namespace Tests\Feature;

  use Tests\TestCase;

  class SessionTest extends TestCase
  {
      public function test_session_value(): void
      {
          $response = $this->withSession(['locale' => 'ja'])->get('/');

          $response->assertSessionHas('locale', 'ja');
      }
  }
  ```
</CodeGroup>

### Overzicht van sessie-assertions

| Methode                                 | Beschrijving                                        |
| --------------------------------------- | --------------------------------------------------- |
| `assertSessionHas($key, $value)`        | De opgegeven sleutel en waarde bestaan in de sessie |
| `assertSessionHasAll([...])`            | Meerdere sleutels en waarden bestaan in de sessie   |
| `assertSessionHasErrors($keys)`         | Er bestaan validatiefouten in de sessie             |
| `assertSessionHasErrorsIn($bag, $keys)` | Er bestaan fouten in de opgegeven error bag         |
| `assertSessionHasNoErrors()`            | Er bestaan geen validatiefouten in de sessie        |
| `assertSessionDoesntHaveErrors()`       | Er bestaan geen validatiefouten in de sessie        |
| `assertSessionMissing($key)`            | De opgegeven sleutel bestaat niet in de sessie      |

## Bestandsuploads testen

Met de methode `fake()` van de klasse `Illuminate\Http\UploadedFile` genereer je dummybestanden of -afbeeldingen.
In combinatie met de methode `fake()` van de `Storage`-facade test je bestandsuploads eenvoudig.

<CodeGroup>
  ```php Pest theme={null}
  <?php

  use Illuminate\Http\UploadedFile;
  use Illuminate\Support\Facades\Storage;

  test('avatarafbeelding kan worden geüpload', function () {
      Storage::fake('avatars');

      $file = UploadedFile::fake()->image('avatar.jpg');

      $response = $this->post('/avatar', [
          'avatar' => $file,
      ]);

      Storage::disk('avatars')->assertExists($file->hashName());
  });
  ```

  ```php PHPUnit theme={null}
  <?php

  namespace Tests\Feature;

  use Illuminate\Http\UploadedFile;
  use Illuminate\Support\Facades\Storage;
  use Tests\TestCase;

  class AvatarTest extends TestCase
  {
      public function test_avatars_can_be_uploaded(): void
      {
          Storage::fake('avatars');

          $file = UploadedFile::fake()->image('avatar.jpg');

          $response = $this->post('/avatar', [
              'avatar' => $file,
          ]);

          Storage::disk('avatars')->assertExists($file->hashName());
      }
  }
  ```
</CodeGroup>

Om te controleren dat een bestand niet bestaat, gebruik je `assertMissing()`.

```php theme={null}
Storage::disk('avatars')->assertMissing('missing.jpg');
```

### Dummybestanden aanpassen

Je kunt de afmetingen en bestandsgrootte van afbeeldingen opgeven. Handig voor het testen van validatieregels.

```php theme={null}
// Breedte, hoogte en bestandsgrootte opgeven (grootte in KB)
UploadedFile::fake()->image('avatar.jpg', $width, $height)->size(100);

// Een willekeurig bestandstype aanmaken
UploadedFile::fake()->create('document.pdf', $sizeInKilobytes);

// Het MIME-type expliciet opgeven
UploadedFile::fake()->create(
    'document.pdf', $sizeInKilobytes, 'application/pdf'
);
```

## Views testen

Je kunt views direct renderen en testen zonder een HTTP-request te simuleren.
De methode `view()` accepteert een viewnaam en optioneel een array met data, en geeft een instantie van `Illuminate\Testing\TestView` terug.

<CodeGroup>
  ```php Pest theme={null}
  <?php

  test('de welkomstview wordt gerenderd', function () {
      $view = $this->view('welcome', ['name' => 'Taylor']);

      $view->assertSee('Taylor');
  });
  ```

  ```php PHPUnit theme={null}
  <?php

  namespace Tests\Feature;

  use Tests\TestCase;

  class ViewTest extends TestCase
  {
      public function test_a_welcome_view_can_be_rendered(): void
      {
          $view = $this->view('welcome', ['name' => 'Taylor']);

          $view->assertSee('Taylor');
      }
  }
  ```
</CodeGroup>

Op de `TestView`-klasse zijn de volgende assertion-methoden beschikbaar.

| Methode                       | Beschrijving                                                |
| ----------------------------- | ----------------------------------------------------------- |
| `assertSee($value)`           | De view bevat de opgegeven string                           |
| `assertSeeInOrder([...])`     | De view bevat de opgegeven strings in volgorde              |
| `assertSeeText($value)`       | De tekst van de view bevat de opgegeven string              |
| `assertSeeTextInOrder([...])` | De tekst van de view bevat de opgegeven strings in volgorde |
| `assertDontSee($value)`       | De view bevat de opgegeven string niet                      |
| `assertDontSeeText($value)`   | De tekst van de view bevat de opgegeven string niet         |

Om de inhoud van de gerenderde view als string op te halen, cast je de `TestView`-instantie naar een string.

```php theme={null}
$contents = (string) $this->view('welcome');
```

Om validatiefouten door te geven aan een view gebruik je `withViewErrors()`.

```php theme={null}
$view = $this->withViewErrors([
    'name' => ['Voer een geldige naam in.']
])->view('form');

$view->assertSee('Voer een geldige naam in.');
```

### Componenten testen

Met de methode `blade()` render je een ruwe Blade-templatestring.

```php theme={null}
$view = $this->blade(
    '<x-component :name="$name" />',
    ['name' => 'Taylor']
);

$view->assertSee('Taylor');
```

Met de methode `component()` render je een Blade-component. Deze geeft een instantie van `Illuminate\Testing\TestComponent` terug.

```php theme={null}
$view = $this->component(Profile::class, ['name' => 'Taylor']);

$view->assertSee('Taylor');
```

## Overzicht van response-assertions

De belangrijkste assertion-methoden van de klasse `Illuminate\Testing\TestResponse`.

### HTTP-status

| Methode                          | Beschrijving              |
| -------------------------------- | ------------------------- |
| `assertOk()`                     | 200 OK                    |
| `assertCreated()`                | 201 Created               |
| `assertAccepted()`               | 202 Accepted              |
| `assertNoContent($status = 204)` | 204 No Content            |
| `assertBadRequest()`             | 400 Bad Request           |
| `assertUnauthorized()`           | 401 Unauthorized          |
| `assertForbidden()`              | 403 Forbidden             |
| `assertNotFound()`               | 404 Not Found             |
| `assertUnprocessable()`          | 422 Unprocessable Entity  |
| `assertTooManyRequests()`        | 429 Too Many Requests     |
| `assertInternalServerError()`    | 500 Internal Server Error |
| `assertStatus($code)`            | De opgegeven statuscode   |
| `assertSuccessful()`             | Een 2xx-statuscode        |
| `assertClientError()`            | Een 4xx-statuscode        |
| `assertServerError()`            | Een 5xx-statuscode        |

### Redirects

| Methode                                       | Beschrijving                              |
| --------------------------------------------- | ----------------------------------------- |
| `assertRedirect($uri)`                        | Redirect naar de opgegeven URI            |
| `assertRedirectContains($string)`             | De redirect-URI bevat de opgegeven string |
| `assertRedirectToRoute($name, $params)`       | Redirect naar de opgegeven route          |
| `assertRedirectToSignedRoute($name, $params)` | Redirect naar de opgegeven signed route   |
| `assertRedirectBack()`                        | Redirect naar de vorige URL               |

### Content

| Methode                              | Beschrijving                                         |
| ------------------------------------ | ---------------------------------------------------- |
| `assertSee($value, $escaped = true)` | De opgegeven waarde komt voor in de response         |
| `assertSeeInOrder(array $values)`    | De opgegeven waarden komen in volgorde voor          |
| `assertSeeText($value)`              | De opgegeven tekst komt voor                         |
| `assertDontSee($value)`              | De opgegeven waarde komt niet voor                   |
| `assertDontSeeText($value)`          | De opgegeven tekst komt niet voor                    |
| `assertContent($value)`              | De responsebody komt overeen met de opgegeven waarde |
| `assertDownload($filename)`          | Het is een downloadresponse                          |

### JSON

| Methode                                    | Beschrijving                                                          |
| ------------------------------------------ | --------------------------------------------------------------------- |
| `assertJson(array $data)`                  | De JSON-response bevat de opgegeven data                              |
| `assertExactJson(array $data)`             | De JSON-response komt exact overeen met de opgegeven data             |
| `assertJsonPath($path, $value)`            | De waarde op het opgegeven pad komt overeen                           |
| `assertJsonMissingPath($path)`             | Het opgegeven pad bestaat niet                                        |
| `assertJsonStructure(array $structure)`    | De JSON heeft de opgegeven structuur                                  |
| `assertJsonCount($count, $key)`            | De JSON van de opgegeven sleutel heeft het opgegeven aantal elementen |
| `assertJsonFragment(array $data)`          | De JSON bevat het opgegeven fragment                                  |
| `assertJsonMissing(array $data)`           | De JSON bevat de opgegeven data niet                                  |
| `assertJsonIsArray()`                      | De JSON is een array                                                  |
| `assertJsonIsObject()`                     | De JSON is een object                                                 |
| `assertJsonValidationErrors($keys)`        | Er zijn validatiefouten voor de opgegeven sleutels                    |
| `assertJsonMissingValidationErrors($keys)` | Er zijn geen validatiefouten voor de opgegeven sleutels               |

### Headers en cookies

| Methode                             | Beschrijving                                  |
| ----------------------------------- | --------------------------------------------- |
| `assertHeader($headerName, $value)` | De opgegeven header bestaat                   |
| `assertHeaderMissing($headerName)`  | De opgegeven header bestaat niet              |
| `assertCookie($name, $value)`       | De opgegeven cookie bestaat                   |
| `assertCookieExpired($name)`        | De opgegeven cookie is verlopen               |
| `assertCookieMissing($name)`        | De opgegeven cookie bestaat niet              |
| `assertPlainCookie($name, $value)`  | De opgegeven niet-versleutelde cookie bestaat |

### Views

| Methode                         | Beschrijving                              |
| ------------------------------- | ----------------------------------------- |
| `assertViewIs($value)`          | De opgegeven view is teruggegeven         |
| `assertViewHas($key, $value)`   | De opgegeven data bestaat in de view      |
| `assertViewHasAll(array $data)` | Meerdere datawaarden bestaan in de view   |
| `assertViewMissing($key)`       | De opgegeven data bestaat niet in de view |

### Validatie

| Methode                | Beschrijving                                    |
| ---------------------- | ----------------------------------------------- |
| `assertValid($keys)`   | Geen validatiefouten voor de opgegeven sleutels |
| `assertInvalid($keys)` | Validatiefouten voor de opgegeven sleutels      |

## Tips om TDD in de praktijk te brengen

<Tip>
  HTTP-tests passen uitstekend bij TDD (testgedreven ontwikkeling). Houd de volgende punten in gedachten voor het beste resultaat.
</Tip>

<AccordionGroup>
  <Accordion title="Begin met feature-tests">
    HTTP-tests maak je aan in de directory `tests/Feature/`. Door eerst het gedrag van buitenaf te definiëren (request → response) wordt duidelijk welke functionaliteit je moet implementeren.
  </Accordion>

  <Accordion title="Gebruik RefreshDatabase">
    Gebruik in tests die de database gebruiken de trait `RefreshDatabase`. Na elke test wordt de database gereset, waardoor data-interferentie tussen tests wordt voorkomen. Door tests onafhankelijk te houden bouw je een stabiele testsuite die niet afhangt van de uitvoeringsvolgorde.
  </Accordion>

  <Accordion title="Gebruik factory's actief">
    Met modelfactory's zoals `User::factory()->create()` maak je testdata eenvoudig aan. Door factory-states te definiëren voor modellen met een specifieke toestand verbeter je de leesbaarheid van je tests.
  </Accordion>

  <Accordion title="Eén test, één assertion">
    Verifieer in één testmethode zo veel mogelijk maar één ding. Zo is de oorzaak makkelijker te achterhalen wanneer een test faalt. Met het AAA-patroon "Arrange (voorbereiden) → Act (uitvoeren) → Assert (verifiëren)" in gedachten worden je tests leesbaarder.
  </Accordion>

  <Accordion title="Vergeet authenticatietests niet">
    Schrijf voor routes die authenticatie vereisen altijd tests voor zowel het "geauthenticeerde" als het "niet-geauthenticeerde" geval. Zo ontdek je beveiligingsproblemen vroegtijdig.
  </Accordion>
</AccordionGroup>

## Gerelateerde pagina's

<Card title="Introductie tot testen" icon="flask" href="/nl/testing">
  Bekijk de basis van het schrijven van tests in Laravel en het gebruik van `php artisan test`.
</Card>


## Related topics

- [Introductie testen](/nl/testing.md)
- [Laravel-updates van juli 2026](/nl/blog/changelog/202607.md)
- [Geavanceerd testen met Pest](/nl/advanced/testing-pest.md)
- [Ontwikkelgids voor apps met de engine-API - VOICEVOX for Laravel](/nl/packages/laravel-voicevox/app-guide.md)
- [HTTP-client](/nl/http-client.md)
