.github/workflows | ||
src | ||
tests | ||
.gitignore | ||
composer.json | ||
LICENSE | ||
phpcs.xml.dist | ||
phpdoc.dist.xml | ||
phpmd.xml | ||
phpstan.neon | ||
phpunit.xml.dist | ||
README.md |
pock
Easy to use HTTP mocking solution, compatible with PSR-18 and HTTPlug.
Project is still in its early development stage. API can change over time, but I'll try to not introduce breaking changes. You can find autogenerated documentation here or look at the examples.
Examples
Mock JSON API route with Basic authorization, reply with JSON.
use Pock\Enum\RequestMethod;
use Pock\Enum\RequestScheme;
use Pock\PockBuilder;
$builder = new PockBuilder();
$builder->matchMethod(RequestMethod::GET)
->matchScheme(RequestScheme::HTTPS)
->matchHost('example.com')
->matchPath('/api/v1/users')
->matchHeaders([
'Content-Type' => 'application/json',
'Authorization' => 'Basic YWxhZGRpbjpvcGVuc2VzYW1l'
])
->reply(200)
->withHeader('Content-Type', 'application/json')
->withJson([
[
'name' => 'John Doe',
'username' => 'john',
'email' => 'john@example.com'
],
[
'name' => 'Jane Doe',
'username' => 'jane',
'email' => 'jane@example.com'
],
]);
// Pass PSR-18 compatible client to the API client.
$client = new MysteriousApiClient($builder->getClient());
$client->setCredentials('username', 'password');
// Receive mock response.
$response = $client->getUsers();
Same mock, but with models! Also, the code itself is slightly shorter.
use Pock\Enum\RequestMethod;
use Pock\PockBuilder;
$builder = new PockBuilder();
$builder->matchMethod(RequestMethod::GET)
->matchUri('https://example.com/api/v1/users')
->matchHeaders([
'Content-Type' => 'application/json',
'Authorization' => 'Basic YWxhZGRpbjpvcGVuc2VzYW1l'
])
->reply(200)
->withHeader('Content-Type', 'application/json')
->withJson([
// We're assuming here that MysteriousUser's constructor can receive an initial values.
new MysteriousUser('John Doe', 'john', 'john@example.com'),
new MysteriousUser('Jane Doe', 'jane', 'jane@example.com'),
]);
// Pass PSR-18 compatible client to the API client.
$client = new MysteriousApiClient($builder->getClient());
$client->setCredentials('username', 'password');
// Receive mock response.
$response = $client->getUsers();
It is possible to mock a response using DTO's because pock can use third-party serializers under the hood.
Serializer support
pock supports JMS serializer and Symfony serializer out of the box. Available serializer will be instantiated automatically.
It will be used to serialize requests and responses in mocks which means you actually can pass an entire DTO
into the corresponding methods (for example, matchJsonBody
as an assertion or withJsonBody
to generate a response body).
By default, JMS serializer has more priority than the Symfony serializer. You can use methods below before running tests (bootstrap.php
)
if you want to override default behavior.
use Pock\Factory\JsonSerializerFactory;
use Pock\Factory\XmlSerializerFactory;
use Pock\Serializer\SymfonySerializerDecorator;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
$encoders = [new XmlEncoder(), new JsonEncoder()];
$normalizers = [new ObjectNormalizer()];
$serializer = new SymfonySerializerDecorator(new Serializer($normalizers, $encoders));
JsonSerializerFactory::setSerializer($serializer);
XmlSerializerFactory::setSerializer($serializer);
In order to use unsupported serializer you should create a decorator which implements Pock\Serializer\SerializerInterface
.
Roadmap to stable
at(N)
- execute mock only at Nth call.after(N)
- allow mock execution only after Nth call (for using with repeat or always).always()
- always execute this mock (removes mock expiration).- Regexp matchers for body, query and path.
- Separate
UniversalMockException
into several exceptions (PockClientException
,PockNetworkException
, etc). - Add methods for easier throwing of exceptions listed in previous entry.
replyCallback
- reply using specified callback.replyFactory
- reply using specified response factory (provide corresponding interface).- Compare XML bodies using
DOMDocument
, fallback to text comparison in case of problems. - Document everything (with examples if it’s feasible).