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

Pact Php Laravel Package

pact-foundation/pact-php

PHP implementation of the Pact consumer-driven contract testing framework. Define contracts between services, run provider verification, and integrate with PHPUnit/CI to prevent breaking API changes. Supports HTTP interactions, mock servers, and Pact Broker workflows.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Package

    composer require pact-foundation/pact-php
    

    For consumer-driven testing, use pact-foundation/pact-php-consumer; for provider verification, use pact-foundation/pact-php-provider.

  2. Configure Pact Add to composer.json:

    "config": {
        "pact": {
            "consumer": "YourConsumerApp",
            "provider": "YourProviderApp",
            "broker": "http://localhost:9292" // Optional: Pact Broker URL
        }
    }
    

    Or set via environment variables (e.g., .env):

    PACT_CONSUMER=YourConsumerApp
    PACT_PROVIDER=YourProviderApp
    
  3. First Consumer Test

    use Pact\Consumer\Message\Message;
    use Pact\Consumer\Interaction;
    use Pact\Consumer\Model\Consumer;
    
    $pact = new Consumer('YourConsumerApp', new Provider('YourProviderApp', 'localhost', 1234));
    $pact->given('a default state')
         ->uponReceiving('a request to fetch user')
         ->withRequest('get', '/users/1', [], '{"id":1}')
         ->willRespondWith(200, ['Content-Type' => 'application/json'], '{"id":1,"name":"John"}');
    
    $pact->verify();
    
  4. First Provider Test

    use Pact\Provider\Verifier\Verifier;
    use Pact\Provider\Verifier\ProviderVerifier;
    
    $verifier = new ProviderVerifier(
        new Verifier(),
        'YourProviderApp',
        'localhost',
        1234,
        'http://localhost:9292' // Pact Broker
    );
    
    $verifier->verify();
    

Implementation Patterns

Consumer Workflow

  1. Define Contracts in Tests Use Pact\Consumer\MockServiceBuilder to mock provider interactions:

    $mockServer = new MockServiceBuilder($pact)
        ->setPort(1234)
        ->setHostName('localhost')
        ->build();
    $mockServer->start();
    

    Run tests against the mock server to ensure consumer expectations are met.

  2. Publish Pact Files After tests pass, publish the pact file to a Pact Broker:

    $pact->publishToBroker('http://localhost:9292');
    

    Or via CLI:

    ./vendor/bin/pact-publish --pact-dir=./pacts --broker-base-url=http://localhost:9292
    
  3. Integrate with CI/CD

    • Consumer Pipeline: Run tests against the mock service, publish pacts.
    • Provider Pipeline: Pull latest pacts from the broker and verify.

Provider Workflow

  1. Verify Contracts Use ProviderVerifier to validate that the provider adheres to published contracts:

    $verifier = new ProviderVerifier(
        new Verifier(),
        'YourProviderApp',
        'localhost',
        8000,
        'http://localhost:9292'
    );
    $verifier->verify();
    

    Run this in CI to catch breaking changes early.

  2. Handle Dynamic Data Use state handlers for dynamic responses:

    $pact->given('a user exists with id 1')
         ->uponReceiving('a request to fetch user')
         ->withRequest('get', '/users/1')
         ->willRespondWith(200, [], '{"id":1,"name":"John"}')
         ->toState('user_1_exists');
    

    In your provider, implement a route to transition to this state:

    Route::get('/setup/user_1', function () {
        User::create(['id' => 1, 'name' => 'John']);
        return response()->json(['status' => 'ready']);
    });
    
  3. Partial Verification For large providers, verify contracts incrementally:

    $verifier->verifyProviderState('a default state');
    

Integration Tips

  1. Laravel Service Provider Bootstrap Pact in AppServiceProvider:

    public function boot()
    {
        if ($this->app->environment('testing') && config('pact.enabled')) {
            $mockServer = (new MockServiceBuilder(config('pact')))
                ->setPort(config('pact.port'))
                ->build();
            $mockServer->start();
        }
    }
    
  2. Testing HTTP Clients Use Pact with Laravel HTTP tests:

    public function test_fetch_user()
    {
        $response = Http::get('http://localhost:1234/users/1');
        $response->assertOk();
    }
    
  3. Mocking External APIs Replace real API calls with Pact mocks in unit/integration tests:

    $mockServer = new MockServiceBuilder($pact)
        ->setScheme('https')
        ->setHostName('api.example.com')
        ->build();
    

Gotchas and Tips

Common Pitfalls

  1. Port Conflicts

    • Pact mock servers default to port 1234. Ensure no other service is using it.
    • Fix: Explicitly set a port:
      $mockServer->setPort(1235);
      
  2. State Management

    • Forgetting to implement state handlers in the provider will cause verification to fail.
    • Fix: Always define states in the provider and implement setup routes.
  3. Broker Authentication

    • If using a remote broker (e.g., PactFlow), ensure credentials are configured:
      $verifier->setBrokerAuth('username', 'password');
      
  4. Dynamic Data in Responses

    • Hardcoding dynamic values (e.g., timestamps, IDs) in pacts will cause flaky tests.
    • Fix: Use placeholders like $timestamp and replace them in the provider:
      ->willRespondWith(200, [], '{"created_at":"$timestamp"}')
      

Debugging Tips

  1. Enable Verbose Logging

    $pact->setLogDir(__DIR__.'/logs');
    $pact->setLogLevel(LogLevel::DEBUG);
    
  2. Inspect Pact Files

    • Pact files are stored in ./pacts by default. Validate them manually:
      pact-cli validate ./pacts/consumer-provider.json
      
  3. Provider Verification Failures

    • Use --verbose for detailed output:
      ./vendor/bin/pact-verify-provider --provider YourProviderApp --pact-dir ./pacts --verbose
      

Extension Points

  1. Custom Matchers Extend Pact’s matchers for complex assertions:

    use Pact\Consumer\Model\Matchers\RegexMatcher;
    
    $pact->given('...')
         ->uponReceiving('...')
         ->withRequest('post', '/users', [
             'body' => new RegexMatcher('/{"name":"\w+"}/')
         ]);
    
  2. Custom Providers Implement Pact\Provider\Provider for non-HTTP protocols (e.g., gRPC):

    class CustomProvider implements Provider {
        public function verify(): void {
            // Custom logic
        }
    }
    
  3. Plugin System Use Pact’s plugin architecture to integrate with tools like:

    • Postman: Export pacts as collections.
    • Swagger/OpenAPI: Generate OpenAPI specs from pacts.

Configuration Quirks

  1. Environment-Specific Config Use Laravel’s config caching to switch between dev/staging/prod:

    // config/pact.php
    'enabled' => env('PACT_ENABLED', false),
    'port'    => env('PACT_PORT', 1234),
    
  2. Docker Integration Run Pact Broker in Docker:

    # docker-compose.yml
    services:
      pact_broker:
        image: pactfoundation/pact-broker
        ports:
          - "9292:9292"
    
  3. Parallel Testing

    • Pact mock servers are not thread-safe. Run tests sequentially or use separate ports for parallel suites.
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui