SyntaxStudy
Sign Up
Laravel API Testing and JSON Assertions
Laravel Beginner 1 min read

API Testing and JSON Assertions

Laravel's HTTP test helpers make API testing straightforward. The getJson(), postJson(), putJson(), patchJson(), and deleteJson() methods set the Accept: application/json header automatically, ensuring the application returns JSON responses rather than HTML redirects for errors. They also encode the request body as JSON and set the Content-Type header. The assertJson() method performs a partial match against the response JSON — the response can contain additional keys and still pass. The assertExactJson() method requires an exact match including key order. The assertJsonStructure() method validates that specific keys exist in the JSON at the expected nesting level. The assertJsonCount() method verifies the number of items in a JSON array. For testing JSON:API compliant responses, assertJsonPath() accepts a dot-notation path and an expected value: $response->assertJsonPath('data.0.title', 'Hello World'). Testing pagination involves checking the meta and links keys that Laravel's paginator adds automatically. The assertJsonMissing() method confirms that sensitive fields like passwords and tokens are not leaked in responses.
Example
<?php
// tests/Feature/Api/PostApiTest.php

namespace Tests\Feature\Api;

use App\Models\Post;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class PostApiTest extends TestCase
{
    use RefreshDatabase;

    private User $user;

    protected function setUp(): void
    {
        parent::setUp();
        $this->user = User::factory()->create();
    }

    public function test_can_list_published_posts(): void
    {
        Post::factory(3)->published()->create();

        $this->actingAs($this->user, 'sanctum')
            ->getJson('/api/v1/posts')
            ->assertOk()
            ->assertJsonStructure([
                'data' => [['id', 'title', 'slug', 'status', 'author']],
                'links' => ['first', 'last', 'prev', 'next'],
                'meta'  => ['total', 'per_page', 'current_page'],
            ])
            ->assertJsonCount(3, 'data');
    }

    public function test_returns_404_for_missing_post(): void
    {
        $this->actingAs($this->user, 'sanctum')
            ->getJson('/api/v1/posts/9999')
            ->assertNotFound()
            ->assertJsonPath('message', 'Resource not found.');
    }

    public function test_validation_errors_return_422(): void
    {
        $this->actingAs($this->user, 'sanctum')
            ->postJson('/api/v1/posts', [])
            ->assertUnprocessable()
            ->assertJsonValidationErrors(['title', 'body', 'status']);
    }
}

This is the last lesson in this section.

Create a free account to earn a certificate