We previously discussed how Laravel's assertViewHas
test helper behaves when trying to assert a value is null
. Today, we'll talk about another issue that might catch you off guard if you don't know how the assertion works internally.
Let's say you're trying to test for a boolean value, or a specific numeric value. You might try something like this:
$response->assertViewHas('status', false);
$response->assertViewHas('recordCount', 1);
This seems pretty straightforward, but it may not work quite as you expect:
$response->assertViewHas('status', false); // passes when status is `null` or `0`
$response->assertViewHas('recordCount', 1); // passes when recordCount is `true`
What is happening here? Under the hood, assertViewHas
uses PHPUnit's assertEquals
assertion, which does a loose comparison of the expected and actual values. If your controller is passing a mixed type, this can cause your test to pass, when you might be expecting it to fail.
What is the solution? My recommendation is to avoid the use of mixed types where possible. For example, if status
is always a boolean, there's no possibility for type coercion to confuse the loose comparison. If recordCount
is always an integer, you avoid the same issue.
If you absolutely can't avoid a mixed type, you can use a closure to do a strict comparison and avoid the ambiguity.
$response->assertViewHas('status', fn ($value) => $value === false);
$response->assertViewHas('recordCount', fn ($value) => $value === 1);
Here to help,
Joel
P.S. You think this tip is good? You should try our free book of even more Laravel tips to make your application a little bit better.