Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Api Test Cases Laravel Package

app-verk/api-test-cases

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Bundle:

    composer require app-verk/api-test-cases
    

    Ensure AppVerk\ApiTestCasesBundle\ApiTestCasesBundle is enabled in config/bundles.php.

  2. Extend Base Test Case: Create a test class extending JsonApiTestCase:

    use AppVerk\ApiTestCasesBundle\Api\Cases\JsonApiTestCase;
    
    class MyApiTest extends JsonApiTestCase
    {
        // Your test methods here
    }
    
  3. Configure Test Fixtures: Use app-verk/alice-bundle for fixture loading (included as a dependency). Example fixture:

    # config/packages/test/alice.yaml
    alice:
        fixtures:
            - '%kernel.project_dir%/tests/fixtures/users.yml'
    
  4. First Test Case:

    public function testGetUser()
    {
        $this->loadFixtures(['users.yml']);
        $response = $this->client->get('/api/users/1');
        $this->assertResponse($response, 'users/success', Response::HTTP_OK);
    }
    

Key Files to Review

  • src/Api/Cases/JsonApiTestCase.php: Core test case class with assertions.
  • tests/fixtures/: Directory for Alice fixture files (e.g., users.yml).
  • config/packages/test/: Test-specific configurations (e.g., alice.yaml, security.yaml).

Implementation Patterns

Workflow: TDD with API Tests

  1. Define Expected Responses: Create schema files (e.g., users/success.json) in tests/data/ to define expected API responses. Example (users/success.json):

    {
        "id": 1,
        "name": "John Doe",
        "email": "john@example.com"
    }
    
  2. Load Fixtures: Use Alice fixtures to populate the database for tests:

    protected function setUp(): void
    {
        $this->loadFixtures(['users.yml']);
        parent::setUp();
    }
    
  3. Assert Responses:

    public function testCreateUser()
    {
        $response = $this->client->post('/api/users', [
            'json' => ['name' => 'Jane Doe', 'email' => 'jane@example.com']
        ]);
        $this->assertResponse($response, 'users/success', Response::HTTP_CREATED);
    }
    
  4. Authentication: Reuse the authenticateFixtureUser pattern for JWT/OAuth:

    protected function authenticate()
    {
        $this->authenticateFixtureUser('users/admin.yml');
    }
    

Integration Tips

  • Symfony Mocker Container: Use polishsymfonycommunity/symfony-mocker-container to mock services in tests:

    $container = $this->createMockContainer();
    $container->get('some.service')->method('doSomething')->willReturn(true);
    
  • Guzzle HTTP Client: Leverage Guzzle for external API testing (included via guzzlehttp/guzzle):

    $client = new Client(['base_uri' => 'http://api.example.com']);
    $response = $client->get('/endpoint');
    $this->assertResponse($response, 'external/success.json');
    
  • Diff Assertions: Use phpspec/php-diff for detailed response comparisons:

    $this->assertJsonStringEqualsJsonFile(
        'tests/data/users/success.json',
        $response->getContent()
    );
    

Gotchas and Tips

Pitfalls

  1. Fixture Loading Order: Fixtures are loaded alphabetically. Explicitly define dependencies in fixture files:

    # users.yml
    AppBundle\Entity\User:
        user1:
            roles: ['ROLE_USER']
            # ...
    
  2. Response Schema Mismatches: Ensure JSON schema files match the actual API response structure. Use php-diff for clear failure messages:

    $this->assertResponseStructure($response, [
        'id' => 'integer',
        'name' => 'string',
        'email' => 'string'
    ]);
    
  3. Static Client State: Avoid test pollution by resetting the client between tests:

    protected function tearDown(): void
    {
        self::$staticClient->setDefaultOption('headers', []);
        parent::tearDown();
    }
    
  4. Symfony 5+ Compatibility: The bundle targets Symfony 3 but may work with 4/5. Override createKernel() if needed:

    protected function createKernel(array $options = []): KernelInterface
    {
        $kernel = parent::createKernel($options);
        $kernel->boot();
        return $kernel;
    }
    

Debugging Tips

  • Enable API Debugging: Add this to config/packages/test/debug.yaml:

    framework:
        router:
            debug: '%kernel.debug%'
    
  • Log Failed Requests: Use Monolog to log failed assertions:

    $this->logger->error('Failed assertion', [
        'response' => $response->getContent(),
        'expected' => file_get_contents('tests/data/users/success.json')
    ]);
    
  • Custom Assertions: Extend JsonApiTestCase to add domain-specific assertions:

    class CustomApiTest extends JsonApiTestCase
    {
        protected function assertTokenExpiry($response, $expiry)
        {
            $data = json_decode($response->getContent(), true);
            $this->assertGreaterThan(time(), $data['exp'], 'Token expiry is valid');
        }
    }
    

Extension Points

  1. Custom Response Validators: Override validateResponse() to add logic:

    protected function validateResponse(Response $response, $expected, $statusCode)
    {
        if ($statusCode === Response::HTTP_UNAUTHORIZED) {
            $this->assertArrayHasKey('error', json_decode($response->getContent(), true));
        }
        parent::validateResponse($response, $expected, $statusCode);
    }
    
  2. Dynamic Fixture Loading: Use traits to centralize fixture logic:

    trait FixtureLoader
    {
        protected function loadUserFixtures()
        {
            $this->loadFixtures(['users/base.yml', 'users/admin.yml']);
        }
    }
    
  3. Parallel Testing: Configure PHPUnit for parallel tests in phpunit.xml.dist:

    <phpunit>
        <extensions>
            <extension class="Parallel\Extension"/>
        </extensions>
    </phpunit>
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity