psr-mock/http-factory-implementation
Lightweight PSR-17/PSR-7 HTTP factory/message mock implementation for PHP 8.1+. Built for SDKs and libraries to test against PSR interfaces without hard deps, with strict PSR compliance and helpful debugging API.
Installation Add the package via Composer (PHP 8.1+ required):
composer require --dev psr-mock/http-factory-implementation:^1.0.1
Ensure your project uses PSR-17 (HttpFactoryInterface) and PSR-7 (MessageInterface, StreamInterface) for HTTP messages.
Basic Setup Import the factory and mock classes:
use PsrMock\HttpFactory\MockHttpFactory;
use PsrMock\HttpFactory\MockStream;
First Use Case: Mocking HTTP Requests Create a mock HTTP factory and request in a test:
$factory = new MockHttpFactory();
$request = $factory->createRequest('GET', '/test');
$request->withHeader('X-Custom-Header', 'value');
Mocking HTTP Messages Use the factory to generate mock requests/responses with predefined headers, body, or status:
$response = $factory->createResponse(200)
->withHeader('Content-Type', 'application/json')
->withBody($factory->createStreamFromString('{"key": "value"}'));
Stream Mocking Simulate file uploads or binary responses:
$stream = new MockStream('file contents');
$request = $factory->createRequest('POST', '/upload')
->withBody($stream);
Integration with Laravel
Replace Laravel’s Symfony\Component\HttpFoundation or GuzzleHttp dependencies in tests:
$this->app->instance(\Psr\Http\Message\RequestInterface::class, $factory->createRequest('GET', '/'));
Dynamic Mocking Use closures for dynamic responses (e.g., based on request data):
$factory->setResponseCallback(function ($request) {
return $factory->createResponse(200)
->withBody($factory->createStreamFromString($request->getBody()->getContents()));
});
Unit Testing Controllers Mock the HTTP factory to isolate logic:
$request = $factory->createRequest('GET', '/api/data');
$response = $this->app->handle($request);
$this->assertEquals(200, $response->getStatusCode());
Mocking External APIs
Replace HttpClient (e.g., Guzzle) with a mock factory:
$client = new class($factory) implements \Psr\Http\Client\ClientInterface {
public function sendRequest(RequestInterface $request) {
return $this->factory->createResponse(200);
}
};
PHP Version Requirement
^1.0.0) if needed.Stream Behavior
MockStream::fromFile() for file-based streams:
$stream = MockStream::fromFile('/path/to/file');
Header/Body Mutability
withHeader() return a new instance (immutable). Chain methods carefully:
// Correct:
$response = $factory->createResponse(200)
->withHeader('X-Test', '1')
->withHeader('X-Test', '2'); // Overwrites
PSR Compliance
getBody() returns StreamInterface), not concrete classes.Laravel-Specific Quirks
Http facade, bind the mock factory to the container:
$this->app->bind(\Psr\Http\Message\RequestFactoryInterface::class, function () use ($factory) {
return $factory;
});
var_dump($request->getHeaders()) or dd($response->getBody()->getContents()) to verify state.$factory = new MockHttpFactory(); // Fresh instance per test
Custom Mock Classes
Extend MockHttpFactory or MockStream for domain-specific logic:
class CustomStream extends MockStream {
public function __toString() { return 'custom'; }
}
Middleware Testing Use the factory to simulate middleware behavior:
$request = $factory->createRequest('GET', '/')
->withHeader('Authorization', 'Bearer token');
$middleware = new AuthMiddleware();
$response = $middleware->process($request, function () { return $factory->createResponse(200); });
Performance For large-scale tests, pre-generate mocks and reuse them (but be mindful of state).
How can I help you explore Laravel packages today?