As of https://github.com/laravel/framework/commit/cfab97fbed78c1eddb9a570edcf69122ae197029 which was released in 5.7.14, if you return null as a JSON response and your tests are using assertJson() to check the response, you will get an unexpected exception that did not occur on 5.7.13.
I have seen this happen most often on routes that return an optional hasOne relationship result where the result will be either a model object from the relationship or null.
Create a fresh Laravel installation of at least 5.7.14 and add this route to your routes/api.php file:
Route::get('empty-failure', function () {
return response()->json(null);
});
Then in your example feature test add this test:
public function testEmptyFailure()
{
$response = $this->get('/api/empty-failure');
$response->assertJson(['foo' => 'bar']);
}
Run that on 5.7.14 and you will see that it fails with this exception message:
There was 1 error:
1) Tests\Feature\ExampleTest::testEmptyFailure
PHPUnit\Framework\Exception: Argument #2 (No Value) of PHPUnit\Framework\Assert::assertArraySubset() must be a array or ArrayAccess
/home/vagrant/code/14/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestResponse.php:425
/home/vagrant/code/14/tests/Feature/ExampleTest.php:14
Do this same setup on 5.7.13 (or lower) and you will see that the test fails with an accurate and useful message saying that the expected JSON was not found.
I realize that using assertJson([]) is particularly useless, but it does bring to attention the issue that decodeResponseJson is returning objects now that are being passed to PHPUnit's assert array functions.
I don't see the function referred in the commit you mentioned. But the issue still persists though
@srmklive decodeResponseJson was already in the code base, but it used to just call json_decode($this->getContent(), true)
In the commit I referenced it was changed to use a new function called jsonDecodeKeepEmptyObject, which was then renamed in later commits to be decodeJsonWhilePreservingEmptyObjects (see https://github.com/laravel/framework/commit/e6ebc8d239e53e6daf16c869de3897ffbce6c751 and https://github.com/laravel/framework/commit/621d91d802016ab4a64acc5c65f81cb9f5e5f779).
I just did some more testing and if you ever have null returned as a JSON response (such as when you have an endpoint that returns the result of a hasOne relationship that can be null) you will no longer get a helpful test failure message if you use assertJson on the response. No matter what your assertion is, if the JSON response is null (which comes back as an empty JSON object) you will see the exception mentioned in the ticket description.
This makes it very confusing if you are testing endpoints that may have a bug which is returning an empty JSON object response and you are using assertJson in your tests.
Sent in a PR which now covers this scenario: https://github.com/laravel/framework/pull/26741
assertExactJson([]); check JSON is empty