Skip to content

Instantly share code, notes, and snippets.

@jakzal
Last active January 30, 2022 11:30
Show Gist options
  • Save jakzal/392c341872f3bc52f05e to your computer and use it in GitHub Desktop.
Save jakzal/392c341872f3bc52f05e to your computer and use it in GitHub Desktop.
Faking http responses
<?php
use Symfony\Component\HttpFoundation\Response;
class MyTest extends FakeHttpTestCase
{
public function testFakeResponseString()
{
$this->mockResponse('GET', '/', 'foo');
$content = file_get_contents('http://127.0.0.1:8000/');
$this->assertSame('foo', $content);
}
public function testFakeResponse()
{
$this->mockResponse('GET', '/', new Response('foo'));
$content = file_get_contents('http://127.0.0.1:8000/');
$this->assertSame('foo', $content);
}
public function testFakeCallback()
{
$this->mockResponse(
'GET',
'/',
static function (\Symfony\Component\HttpFoundation\Request $request) {
if ('foo' === $request->headers->get('X-Auth')) {
return new Response('{}', 200, ['Content-Type' => 'application/json']);
} else {
return new Response('Forbidden', 403, ['Content-Type' => 'application/json']);
}
}
);
$content = file_get_contents('http://127.0.0.1:8000/');
$this->assertSame('Forbidden', $content);
}
}
<?php
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
abstract class FakeHttpTestCase extends \PHPUnit_Framework_TestCase
{
const APP_URL = 'http://127.0.0.1:8000';
/**
* @var array
*/
private $fakedRequests = array();
protected function tearDown()
{
if (!empty($this->fakedRequests)) {
file_get_contents(self::APP_URL.'/_fakes', false, stream_context_create(array('http' => array('method' => 'DELETE'))));
}
}
/**
* @param string $method
* @param string $uri
* @param string|Response $response
*/
protected function mockResponse($method, $uri, $response)
{
if (is_callable($response)) {
$serializer = new \SuperClosure\Serializer();
$response = $serializer->serialize($response);
} else {
$response = serialize($response);
}
$this->fakedRequests[$uri][$method] = $response;
}
/**
* Call this after faking all responses, but before making requests in your test
*/
protected function fakeResponses()
{
if (!empty($this->fakedRequests)) {
$context = stream_context_create(array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/json',
'content' => json_encode($this->fakedRequests)
)
));
file_get_contents(self::APP_URL.'/_fakes', false, $context);
}
}
}
<?php
require_once __DIR__.'/../vendor/autoload.php';
use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use SuperClosure\Serializer;
$app = new Application(['debug' => true]);
$app->before(function (Request $request, Application $app) {
if (file_exists(sys_get_temp_dir().'/fake-responses.json')) {
$responses = json_decode(file_get_contents(sys_get_temp_dir().'/fake-responses.json'), true);
if (!$responses) {
return new Response('Faked responses file is corrupted', 500);
}
foreach ($responses as $uri => $methods) {
foreach ($methods as $method => $serializedResponse) {
$method = strtolower($method);
if (0 === strpos($serializedResponse, 'C:32:"SuperClosure\SerializableClosure')) {
$serializer = new Serializer();
$callback = $serializer->unserialize($serializedResponse);
$responseCallback = $callback;
} else {
$responseCallback = function () use ($serializedResponse) {
return unserialize($serializedResponse);
};
}
$app->$method($uri, $responseCallback);
}
}
$app->flush();
}
}, Application::EARLY_EVENT);
$app->post('/_fakes', function (Request $request) {
file_put_contents(sys_get_temp_dir().'/fake-responses.json', $request->getContent());
return new Response(null, 201);
});
$app->delete('/_fakes', function (Request $request) {
if (file_exists(sys_get_temp_dir().'/fake-responses.json')) {
unlink(sys_get_temp_dir().'/fake-responses.json');
}
return new Response(null, 202);
});
$app->run();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment