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);