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

Easy Api Tests Laravel Package

citizen63000/easy-api-tests

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup for Laravel

  1. Install the Package Add to composer.json (adjust version if needed):

    composer require citizen63000/easy-api-tests
    

    Note: Laravel compatibility is implied via Symfony 6.4, but verify PHP 8.1+ and Laravel 10+.

  2. First Use Case: API Test Scaffold Create a test class extending the package’s base:

    // tests/Feature/ExampleApiTest.php
    use Citizen63000\EasyApiTests\TestCase;
    
    class ExampleApiTest extends TestCase
    {
        public function test_get_endpoint_returns_data(): void
        {
            $response = $this->get('/api/example');
            $response->assertStatus(200)
                    ->assertJsonStructure(['data']);
        }
    }
    

    Key: The TestCase provides Laravel/Symfony hybrid assertions (e.g., assertJsonStructure, assertDatabaseHas).

  3. Where to Look First

    • TestCase Class: vendor/citizen63000/easy-api-tests/src/TestCase.php for available methods.
    • Symfony 6.4 Docs: Symfony Test Components for advanced usage (e.g., client mocking).
    • Laravel Testing Docs: HTTP Tests for Laravel-specific features (e.g., actingAs).

Implementation Patterns

Workflows

  1. API Contract Testing Use the package’s assertions to validate responses against OpenAPI/Swagger specs:

    public function test_create_user_matches_schema(): void
    {
        $response = $this->postJson('/api/users', ['name' => 'John']);
        $response->assertStatus(201)
                ->assertJsonMatchesSchema([
                    'type' => 'object',
                    'properties' => [
                        'id' => ['type' => 'integer'],
                        'name' => ['type' => 'string']
                    ]
                ]);
    }
    
  2. Authentication Flows Leverage Laravel’s built-in auth helpers with Symfony’s client:

    public function test_protected_route_requires_auth(): void
    {
        $this->actingAs(User::factory()->create())
             ->get('/api/protected')
             ->assertOk();
    
        $this->get('/api/protected')
             ->assertUnauthorized();
    }
    
  3. Database Transactions Use Symfony’s DatabaseTransactionTrait (if included) for atomic tests:

    use Citizen63000\EasyApiTests\DatabaseTransactionTrait;
    
    class UserTest extends TestCase
    {
        use DatabaseTransactionTrait;
    
        public function test_user_creation_persists_data(): void
        {
            $this->postJson('/api/users', ['name' => 'Alice']);
            $this->assertDatabaseHas('users', ['name' => 'Alice']);
        }
    }
    

Integration Tips

  • Hybrid Assertions: Combine Laravel’s assertDatabaseHas with Symfony’s assertResponseStatus:

    $response = $this->postJson('/api/orders', ['product_id' => 1]);
    $response->assertCreated()
             ->assertJsonPath('data.id', 1);
    $this->assertDatabaseHas('orders', ['product_id' => 1]);
    
  • Mocking External APIs: Use Symfony’s HttpClient mocking (if supported):

    $mockHandler = new MockHandler([
        new Response(200, [], json_encode(['key' => 'value']))
    ]);
    $client = new Client(['handler' => $mockHandler]);
    $this->app->instance(HttpClient::class, $client);
    
  • Feature Flags for Tests: Enable/disable test suites via Laravel’s config('testing.enabled') or Symfony’s TEST_ENVIRONMENT=true.


Gotchas and Tips

Pitfalls

  1. Symfony 6.4 Breaking Changes

    • Deprecated APIs: Symfony 6.4 drops Request::getClientIp() in favor of getRealClientIp(). Update custom middleware:
      // Before (deprecated)
      $ip = $request->getClientIp();
      
      // After
      $ip = $request->getRealClientIp();
      
    • PHP 8.1+ Strict Types: Ensure test classes use void return types and named arguments:
      public function test_something(): void { ... } // Required
      
  2. Dependency Conflicts

    • Laravel vs. Symfony Components: If the package pulls in symfony/mailer, conflict with Laravel’s symfony/mailer (v5.x). Resolve via composer.json:
      "conflict-resolution": {
          "symfony/mailer": "6.4.*"
      }
      
    • Transitive Dependencies: Run composer why symfony/* to audit conflicts.
  3. Test Isolation

    • Shared State: Tests may fail if they rely on shared database state. Use DatabaseTransactionTrait or Laravel’s refreshDatabase():
      public function setUp(): void
      {
          parent::setUp();
          $this->artisan('migrate:fresh');
      }
      

Debugging

  • Symfony vs. Laravel Errors: Symfony 6.4 errors may not trigger Laravel’s exception handler. Use:

    php artisan config:clear
    php artisan cache:clear
    

    Or enable Symfony’s debug mode:

    putenv('SYMFONY_DEBUG=1');
    
  • HTTP Client Issues: If HttpClient fails silently, enable verbose logging:

    $client = new Client([
        'headers' => ['User-Agent' => 'EasyApiTests'],
        'debug' => true, // Enable debug output
    ]);
    

Extension Points

  1. Custom Assertions Extend the TestCase to add domain-specific assertions:

    namespace Tests\Feature;
    
    use Citizen63000\EasyApiTests\TestCase;
    
    class CustomAssertionsTestCase extends TestCase
    {
        protected function assertResponseHasPaginatedData(array $expected): void
        {
            $this->assertResponseStatus(200);
            $this->assertJsonStructure([
                'data' => ['*'],
                'meta' => ['pagination' => ['total', 'per_page']]
            ]);
            // Add custom logic...
        }
    }
    
  2. Test Data Factories Integrate Laravel’s factories with Symfony’s test data builders:

    public function test_with_factory_data(): void
    {
        $user = User::factory()->create();
        $this->actingAs($user)
             ->get('/api/profile')
             ->assertOk()
             ->assertJsonPath('data.name', $user->name);
    }
    
  3. Performance Testing Use Symfony’s Stopwatch to measure test execution:

    use Symfony\Component\Stopwatch\Stopwatch;
    
    public function test_performance(): void
    {
        $stopwatch = new Stopwatch();
        $event = $stopwatch->start('api_response_time');
    
        $this->get('/api/heavy-endpoint');
    
        $event->stop();
        $this->assertLessThan(1000, $event->getDuration()); // <1s
    }
    

Configuration Quirks

  • Environment Variables: Ensure .env.testing is loaded for test-specific configs:
    putenv('APP_ENV=testing');
    
  • Service Container: If the package binds services to the container, override them in TestCase:
    protected function getPackageProviders($app): array
    {
        return [
            \Citizen63000\EasyApiTests\ServiceProvider::class,
            // Override specific bindings
        ];
    }
    

Pro Tips

  • Parallel Testing: Use Laravel’s pest --parallel or Symfony’s ParallelTestSuite (if supported) to speed up test suites.
  • Visual Regression: Combine with laravel-shift/visual-regression for API response snapshots:
    $this->assertVisualRegression($response->getContent());
    
  • CI Optimization: Cache dependencies in CI (e.g., GitHub Actions) to reduce test time:
    jobs:
      test:
        steps:
          - uses: actions/cache@v3
            with:
              path: vendor
              key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
    
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.
andydefer/laravel-cluster
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
christhompsontldr/laravel-inky
spatie/mailcoach-vapor
spatie/laravel-javascript-views