Be careful when using assertViewHas with null

Laravel's assertViewHas method doesn't work for null values. Here's how to test for them.

Joel Clermont
Joel Clermont
2023-09-13

Laravel's assertViewHas test helper allows you to confirm that a controller passes a specific value to the Blade view.

In a simple case, you can assert a variable is present with any value: $response->assertViewHas('status')

More often, though, you want to assert what the value actually is: $response->assertViewHas('status', 'active')

This doesn't work if you want to explicitly test for a null value though. Passing null as the second parameter is the same assertion behavior as passing no value at all. It will pass with any value, not just null values. This can be quite surprising!

// these two statements are equivalent
$response->assertViewHas('status');
$response->assertViewHas('status', null); // this passes even if status is `true`

Our approach to work around this is to use a closure with our assertion:

$response->assertViewHas('status', fn ($value) => $value === null);

Or, if you have this in a lot of tests, you can create your own custom test helper:

// register this inside AppServiceProvider::boot()
TestResponse::macro('assertViewHasNull', function (string $key): TestResponse {
    $this->assertViewHas($key, fn ($value) => $value === null);
    return $this;
});

// then in your test you can do
$response->assertViewHasNull('status');

Here to help,

Joel

P.S. Wish you could ship new features more quickly? We can help.

Toss a coin in the jar if you found this helpful.
Want a tip like this in your inbox every weekday? Sign up below 👇🏼

Level up your Laravel skills!

Each 2-minute email has real-world advice you can use.