Summer Sale! All accounts are 50% off this week.

abkrim's avatar
Level 13

Mistake or error in doc about assertJson

Manual says:

Assert that the response contains the given JSON data:

$response->assertJson(array $data, $strict = false);
`` `
> The assertJson method converts the response to an array and utilizes PHPUnit::assertArraySubset to verify that the given array exists within the JSON response returned by the application. So, if there are other properties in the JSON response, this test will still pass as long as the given fragment is present.

But in code, the first parameter is a **string**:

```php
 final public static function assertJson(string $actual, string $message = ''): void
 {
     static::assertThat($actual, static::isJson(), $message);
 }

When I try to test get error

/** @test */
function it_user_is_authorized_can_show_role()
{
    $role1 = Role::find(1);

    $user = User::factory()->create([
        'name' => 'Not authorized'
    ]);

    Bouncer::allow($user)->to('full-roles');

    $this->actingAs($user);

    $response = $this
            ->withHeaders(['Accept' => 'application/json'])
            ->getJson('api/v2/roles/1') // Can return any role
            ->assertOk()
            ->assertExactJson($role1);
}
Tests\Feature\Http\Controllers\RoleControllerTest > it user is authorized can show role                                                                                                                         TypeError   
  PHPUnit\Framework\Assert::assertJson(): Argument #1 ($actual) must be of type string, array given, called in /var/www/html/tests/Feature/Http/Controllers/RoleControllerTest.php on line 160

My version is

php artisan --version
Laravel Framework 10.7.1
0 likes
2 replies
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

The Laracasts forum post is correct in stating that the first parameter of assertJson is an array. The documentation is outdated and needs to be updated. The correct usage of assertJson is to pass an array as the first parameter, which will be converted to JSON and compared to the response. Here is an updated example of the test code:

/** @test */
function it_user_is_authorized_can_show_role()
{
    $role1 = Role::find(1);

    $user = User::factory()->create([
        'name' => 'Not authorized'
    ]);

    Bouncer::allow($user)->to('full-roles');

    $this->actingAs($user);

    $response = $this
        ->withHeaders(['Accept' => 'application/json'])
        ->get('api/v2/roles/1') // Can return any role
        ->assertOk();

    $this->assertJson(['data' => $role1->toArray()]);
}

Note that the $role1 variable needs to be converted to an array using the toArray() method before passing it to assertJson.

1 like
abkrim's avatar
Level 13

@LaryAI Thanks Ai...

First time that you resposne is full ok.

correct code is:

/** @test */
function it_user_is_authorized_can_show_role()
{
   $role1 = Role::find(1)->toArray();

   $user = User::factory()->create([
       'name' => 'Not authorized'
   ]);

   Bouncer::allow($user)->to('full-roles');

   $this->actingAs($user);

   $response = $this
       ->withHeaders(['Accept' => 'application/json'])
       ->getJson('api/v2/roles/1') // Can return any role
       ->assertOk()
       ->assertExactJson(["data" => $role1]);
}

Please or to participate in this conversation.