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('[email protected]'))
            ->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('[email protected]'))
                     ->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('[email protected]'))
                     ->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