Weave 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

Http Laravel Package

psr-mock/http

psr-mock/http is a tiny PHP package for mocking PSR-7 HTTP messages in tests. Create predictable request/response objects without a full HTTP client, helping you unit test middleware, clients, and services with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require --dev psr-mock/http
    

    No configuration required—just autoload the package.

  2. First Use Case: Mocking a Request

    use PsrMock\Http\ServerRequestFactory;
    
    $request = ServerRequestFactory::create()
        ->withMethod('GET')
        ->withUri('/api/users')
        ->withQueryParams(['page' => 1]);
    
    // Use in a test (e.g., with PHPUnit)
    $this->assertEquals('GET', $request->getMethod());
    
  3. First Use Case: Mocking a Response

    use PsrMock\Http\ResponseFactory;
    
    $response = ResponseFactory::create()
        ->withStatus(200)
        ->withHeader('Content-Type', 'application/json')
        ->withBody('{"status": "success"}');
    
    $this->assertEquals(200, $response->getStatusCode());
    

Where to Look First

  • Factory Classes: ServerRequestFactory and ResponseFactory are the entry points.
  • Fluent Interface: Chain methods like withMethod(), withHeader(), etc.
  • PSR-7 Compliance: All returned objects implement ServerRequestInterface or ResponseInterface.

Implementation Patterns

Common Workflows

1. Testing Middleware

$request = ServerRequestFactory::create()
    ->withMethod('POST')
    ->withUri('/login')
    ->withParsedBody(['email' => '[email protected]', 'password' => 'secret']);

$response = $middleware->process($request, $next);

$this->assertEquals(302, $response->getStatusCode());

2. Simulating Form Data

$request = ServerRequestFactory::create()
    ->withMethod('POST')
    ->withUri('/submit')
    ->withUploadedFiles(['file' => new UploadedFileStub()]); // Use a PSR-7 UploadedFileInterface stub

3. JSON API Responses

$response = ResponseFactory::create()
    ->withStatus(200)
    ->withHeader('Content-Type', 'application/json')
    ->withJsonBody(['data' => ['id' => 1, 'name' => 'Test']]);

$body = json_decode($response->getBody(), true);
$this->assertEquals(1, $body['data']['id']);

4. Edge Cases

// Empty body
$request = ServerRequestFactory::create()->withBody('');

// Custom headers
$response = ResponseFactory::create()
    ->withHeader('X-Custom-Header', 'value')
    ->withStatus(404);

Integration Tips

  • Laravel-Specific: Use with Laravel's Http\Testing\TestResponse or Http\Testing\XmlHttpRequest for hybrid testing.
  • Dependency Injection: Register factories as test services in Laravel's testing.php:
    $this->app->singleton(ServerRequestFactory::class, fn() => new ServerRequestFactory());
    
  • Reusability: Create helper methods in a TestCase trait:
    protected function jsonRequest(string $uri, array $data = []): ServerRequestInterface
    {
        return ServerRequestFactory::create()
            ->withMethod('POST')
            ->withUri($uri)
            ->withJsonBody($data);
    }
    

Gotchas and Tips

Pitfalls

  1. Body Handling:

    • Bodies are streams, not strings. Use getBody()->getContents() to read them.
    • Avoid modifying the stream after creation (e.g., rewind() may be needed for repeated reads).
    • Fix: Use withBody() with a Psr7\Stream wrapper if needed:
      use Psr7\Stream;
      $request->withBody(new Stream(fopen('php://memory', 'r+')));
      
  2. Query Params vs. URI:

    • withQueryParams() overwrites the URI. Use withUri() first if you need to preserve path segments:
      $request->withUri('/api/users?sort=name')->withQueryParams(['page' => 1]);
      // URI becomes `/api/users?page=1` (sort=name is lost)
      
  3. Cookies:

    • Cookies are set via headers (Set-Cookie). Use withHeader():
      $response->withHeader('Set-Cookie', ['name=value', 'expires=Mon, 01 Jan 2024 00:00:00 GMT']);
      
  4. Uploaded Files:

    • The package doesn’t mock UploadedFileInterface by default. Use a stub like:
      $uploadedFile = new class implements UploadedFileInterface {
          public function getStream() { /* ... */ }
          public function getSize() { return 1024; }
          // ... other methods
      };
      

Debugging Tips

  • Inspect Headers:
    $headers = $request->getHeaders();
    $this->assertArrayHasKey('content-type', $headers);
    
  • Dump Request/Response:
    $this->assertEquals(
        (string) $request->getBody(),
        '{"key":"value"}'
    );
    
  • Validate PSR-7 Compliance: Use instanceof checks:
    $this->assertInstanceOf(ServerRequestInterface::class, $request);
    

Extension Points

  1. Custom Factories: Extend ServerRequestFactory or ResponseFactory to add domain-specific methods:

    class ApiRequestFactory extends ServerRequestFactory {
        public function withAuthToken(string $token): self {
            return $this->withHeader('Authorization', "Bearer {$token}");
        }
    }
    
  2. Body Helpers: Add methods to handle common payloads:

    $request->withXmlBody('<root><user>Test</user></root>');
    
  3. Laravel Integration: Override Laravel’s Http\Testing\TestResponse to use psr-mock/http:

    use PsrMock\Http\ResponseFactory;
    
    $response = ResponseFactory::create()->withStatus(200);
    $this->assertEquals(200, $response->getStatusCode());
    

Config Quirks

  • No Configuration: The package is stateless and requires zero setup.
  • PSR-7 Implementation: Under the hood, it likely uses nyholm/psr7 or similar. Verify compatibility if mixing with other PSR-7 libraries.
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.
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table