Testing JSON APIs

Laravel Test HTTP Tests: Testing JSON APIs

Testing JSON APIs

$response = $this->postJson('/api/user', ['name' => 'Sally']);

$response
    ->assertStatus(201)
    ->assertJson([
        'created' => true,
    ]);

Asserting Exact JSON Matches

$response
    ->assertStatus(201)
    ->assertExactJson([
        'created' => true,
    ]);

Asserting On JSON Paths

$response
    ->assertStatus(201)
    ->assertJsonPath('team.owner.name', 'Darian');

Fluent JSON Testing

$response
    ->assertJson(fn (AssertableJson $json) =>
        $json->where('id', 1)
            ->where('name', 'Victoria Faith')
            ->where('email', fn ($email) => str($email)->is('victoria@gmail.com'))
            ->whereNot('status', 'pending')
            ->missing('password')
            ->etc()
    );

Understanding The etc Method

This method informs Laravel that there may be other attributes present on the JSON object.

If the etc method is NOT USED, the TEST WILL fail if other attributes that you did not make assertions against exist on the JSON object.

The etc method only ensures that no additional attributes exist at the nesting level in which the etc method is invoked.

Asserting Against JSON Collections

Route::get('/users', function () {
    return User::all();
});

$response
    ->assertJson(fn (AssertableJson $json) =>
        $json->has(3)
             ->first(fn ($json) =>
                $json->where('id', 1)
                     ->where('name', 'Victoria Faith')
                     ->where('email', fn ($email) => str($email)->is('victoria@gmail.com'))
                     ->missing('password')
                     ->etc()
             )
    );

Scoping JSON Collection Assertions

Route::get('/users', function () {
    return [
        'meta' => [...],
        'users' => User::all(),
    ];
});

$response
    ->assertJson(fn (AssertableJson $json) =>
        $json->has('meta')
             ->has('users', 3)
             ->has('users.0', fn ($json) =>
                $json->where('id', 1)
                     ->where('name', 'Victoria Faith')
                     ->where('email', fn ($email) => str($email)->is('victoria@gmail.com'))
                     ->missing('password')
                     ->etc()
             )
    );

Asserting JSON Types

$response->assertJson(fn (AssertableJson $json) =>
    $json->whereType('id', 'integer')
         ->whereAllType([
            'users.0.name' => 'string',
            'meta' => 'array'
        ])
);

$response->assertJson(fn (AssertableJson $json) =>
    $json->whereType('name', 'string|null')
         ->whereType('id', ['string', 'integer'])
);

assertJsonStructure

$response->assertJsonStructure([
    'user' => [
        'name',
    ]
]);

$response->assertJsonStructure([
    'user' => [
        '*' => [
             'name',
             'age',
             'location'
        ]
    ]
]);

Reference