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

Guzzle Fake Server Laravel Package

antwebes/guzzle-fake-server

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require antwebes/guzzle-fake-server:dev-master
    

    (Note: Use dev-master until a stable release is available.)

  2. Basic Configuration: Create a Guzzle client with the fake server plugin:

    use Ant\Bundle\GuzzleFakeServer\Guzzle\Plugin\FakeServer\FakeServer;
    use Ant\Bundle\GuzzleFakeServer\Guzzle\Plugin\FakeServer\FileResourceLoader;
    use Ant\Bundle\GuzzleFakeServer\Guzzle\Plugin\FakeServer\ArrayConfiguration;
    use Guzzle\Client;
    
    $client = new Client();
    $fakeServer = new FakeServer(
        new ArrayConfiguration("http://test-api.com/"),
        new FileResourceLoader(__DIR__ . '/fixtures'),
        200,
        '""',
        ['Content-Type' => 'application/json']
    );
    $client->addSubscriber($fakeServer);
    
  3. First Use Case: Define a mock response for a GET request:

    $fakeServer->getConfiguration()->addGetResource(
        '/users/1',
        'user_1.json',
        200
    );
    
    $response = $client->get('http://test-api.com/users/1');
    // Returns content from `user_1.json` with status 200.
    

Implementation Patterns

Workflow: Mocking API Responses

  1. Define Fixtures: Store JSON/XML files in a structured directory (e.g., tests/fixtures/api/). Example: tests/fixtures/api/users/user_1.json:

    {"id": 1, "name": "John Doe"}
    
  2. Configure Mappings: Use ArrayConfiguration for in-memory mappings or extend ResourceLoaderInterface for custom logic (e.g., database-backed responses).

    $config = $fakeServer->getConfiguration();
    $config->addPostResource(
        '/api/login',
        'auth/success.json',
        200,
        ["email" => "user@example.com", "password" => "secret"]
    );
    
  3. Conditional Responses: Simulate different responses based on request data:

    $config->addPostResource(
        '/api/orders',
        'orders/pending.json',
        201,
        ["status" => "pending"]
    );
    $config->addPostResource(
        '/api/orders',
        'orders/completed.json',
        201,
        ["status" => "completed"]
    );
    
  4. Integration with Laravel: Bind the client to the container in AppServiceProvider:

    public function register()
    {
        $this->app->singleton(GuzzleClient::class, function ($app) {
            $client = new Client();
            $client->addSubscriber(new FakeServer(
                new ArrayConfiguration("http://api.example.com"),
                new FileResourceLoader(__DIR__ . '/../tests/fixtures'),
                200,
                '""',
                ['Content-Type' => 'application/json']
            ));
            return $client;
        });
    }
    
  5. Testing: Use in unit tests to avoid external API calls:

    public function testUserLogin()
    {
        $response = $this->app->make(GuzzleClient::class)->post('/api/login', [
            'email' => 'user@example.com',
            'password' => 'secret'
        ]);
        $this->assertEquals(200, $response->getStatusCode());
        $this->assertJson($response->getBody());
    }
    

Gotchas and Tips

Pitfalls

  1. URL Matching:

    • The fake server matches exact URLs (including query parameters). Use wildcards or regex via custom ConfigurationInterface implementations if needed.
    • Example: /users/{id} won’t work; use /users/1 explicitly.
  2. Case Sensitivity:

    • HTTP methods (GET, POST) are case-sensitive in the configuration methods (e.g., addGetResource vs addgetResource).
  3. Resource Loading:

    • FileResourceLoader throws exceptions if files are missing. Validate paths early in tests:
      if (!file_exists(__DIR__ . '/fixtures/user.json')) {
          throw new \RuntimeException('Fixture file missing!');
      }
      
  4. Guzzle Version:

    • The package requires Guzzle 3.x. If using Laravel 5.5+, pin Guzzle to ~3.7 in composer.json to avoid conflicts.
  5. Event Subscription:

    • Ensure the fake server is added before making requests. Subscribers are processed in order.

Debugging

  1. Verify Mappings: Dump the configuration to debug:

    var_dump($fakeServer->getConfiguration()->getResources());
    
  2. Check Request Data: Log request payloads to ensure conditions match:

    $fakeServer->setOnRequestCallback(function ($request) {
        \Log::debug('Request:', $request->getBody());
    });
    
  3. Status Codes: Default status is 200. Override per route:

    $config->addGetResource('/error', 'error.json', 404);
    

Tips

  1. Dynamic Fixtures: Generate fixtures dynamically using ResourceLoaderInterface:

    class DatabaseResourceLoader implements ResourceLoaderInterface
    {
        public function load($resource)
        {
            return json_encode(['data' => DB::table($resource)->get()]);
        }
    }
    
  2. Headers and Body: Set default headers/body in the FakeServer constructor:

    $fakeServer = new FakeServer(
        $config,
        $loader,
        200,
        '{"default": "response"}', // Default body
        ['X-Custom-Header' => 'value'] // Default headers
    );
    
  3. Laravel Facades: Access the client via Http::client() in tests:

    $response = Http::client()->get('/api/users');
    
  4. Performance: For large test suites, cache loaded resources to avoid disk I/O:

    class CachingResourceLoader implements ResourceLoaderInterface
    {
        private $cache = [];
    
        public function load($resource)
        {
            if (!isset($this->cache[$resource])) {
                $this->cache[$resource] = file_get_contents($resource);
            }
            return $this->cache[$resource];
        }
    }
    
  5. Extending Functionality:

    • Custom Matchers: Implement ConfigurationInterface to support regex or partial matches.
    • Response Modification: Subclass FakeServer to alter responses (e.g., add delays):
      class DelayedFakeServer extends FakeServer
      {
          public function __construct(...$args)
          {
              parent::__construct(...$args);
              $this->setOnResponseCallback(function ($response) {
                  sleep(1); // Simulate network delay
                  return $response;
              });
          }
      }
      
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.
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle
dmstr/api-platform-utils-bundle
dmstr/api-configuration-bundle
chrisdev/ux-components
baks-dev/finances
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