PockBuilder
in package
uses
JsonDecoderTrait, JsonSerializerAwareTrait, XmlSerializerAwareTrait
Defines request expectations and the responses or failures returned by the mock HTTP client.
Each definition combines its matchers with AND and is consumed once by default. Calling a response or exception method finishes the definition; adding another matcher then starts the next definition.
$pock = new PockBuilder();
$pock->matchMethod(RequestMethod::GET)
->matchUri('https://api.example.com/users/42')
->reply(200)
->withJson(['id' => 42]);
$client = $pock->getClient();
Tags
Table of Contents
Methods
- __construct() : mixed
- Creates an empty builder with single-use mocks and no fallback client.
- addMatcher() : self
- Add custom matcher to the mock.
- always() : self
- Always execute this mock if matched. Mock with this call will not be expired ever.
- at() : self
- Match request only at Nth hit. Previous matches will not be executed.
- getClient() : Client
- Create the PSR-18 and HTTPlug client after closing the current definition.
- getSymfonyClient() : HttpClientInterface
- Returns a Symfony HTTP client backed by the configured mocks.
- jsonDecode() : mixed
- json_decode which throws exception on error.
- matchBody() : self
- Match entire request body.
- matchBodyRegExp() : self
- Match entire request body using provided regular expression.
- matchCallback() : self
- Match request using provided callback. Callback should receive RequestInterface and return boolean.
- matchExactFormData() : self
- Match request with form-data. Additional fields aren't allowed.
- matchExactHeader() : self
- Matches request by the exact header pattern or values.
- matchExactHeaders() : self
- Matches request by headers values or several values.
- matchExactQuery() : self
- Match request by its query. Additional query parameters aren't allowed.
- matchFormData() : self
- Match request with form-data.
- matchHeader() : self
- Matches request by header value or several values. Header can have other values which are not specified here.
- matchHeaderLine() : self
- Matches request by the unparsed header line.
- matchHeaderLineRegexp() : self
- Matches request by the unparsed header line using provided regular expression.
- matchHeaders() : self
- Matches request by headers values or several values. Headers can have other values which are not specified here.
- matchHost() : self
- Matches request by hostname.
- matchJsonBody() : self
- Match JSON request body.
- matchMethod() : self
- Match request by its method.
- matchMultipartFormData() : self
- Match request multipart form data. Will not match the request if body is not multipart.
- matchOrigin() : self
- Matches request by origin.
- matchPath() : self
- Match request by its path. Path with and without slash at the start will be treated as the same path.
- matchPathRegExp() : self
- Match request by its path using regular expression. This matcher doesn't care about prefix slash since it's pretty easy to do it using regular expression.
- matchPort() : self
- Matches request by the port.
- matchQuery() : self
- Match request by its query. Request can contain other query variables.
- matchQueryRegExp() : self
- Match request by its query using regular expression.
- matchScheme() : self
- Match request by its scheme.
- matchSerializedJsonBody() : self
- Match JSON request body against JSON string or array with data.
- matchSerializedXmlBody() : self
- Match XML request body.
- matchUri() : self
- Matches request by the whole URI.
- matchUriRegExp() : self
- Matches request by the whole URI using regular expression.
- matchXmlBody() : self
- Match XML request body using raw XML data.
- repeat() : self
- Repeat this mock provided amount of times.
- reply() : PockResponseBuilder
- Start or update a static response and return its fluent response builder.
- replyWith() : void
- Reply to the request with the provided response.
- replyWithCallback() : void
- Construct the response during request execution using provided callback.
- replyWithClient() : void
- Reply to the request using provided client. Can be used to send real network request.
- replyWithFactory() : void
- Construct the response during request execution using a ReplyFactoryInterface implementation.
- reset() : self
- Resets the builder.
- setFallbackClient() : self
- Sets fallback Client. It will be used if no request can be matched.
- throwClientException() : self
- Throw a ClientExceptionInterface instance with specified message.
- throwException() : self
- Throw an exception when request is being sent.
- throwNetworkException() : self
- Throw a NetworkExceptionInterface instance with specified message.
- throwRequestException() : self
- Throw a RequestExceptionInterface instance with specified message.
Methods
__construct()
Creates an empty builder with single-use mocks and no fallback client.
public
__construct() : mixed
$pock = new PockBuilder();
addMatcher()
Add custom matcher to the mock.
public
addMatcher(RequestMatcherInterface $matcher) : self
$pock->addMatcher(new SignedRequestMatcher());
Parameters
- $matcher : RequestMatcherInterface
Return values
selfalways()
Always execute this mock if matched. Mock with this call will not be expired ever.
public
always() : self
$pock->matchPath('/health')->always()->reply(200);
Return values
selfat()
Match request only at Nth hit. Previous matches will not be executed.
public
at(int $hit) : self
Note: There IS a catch if you use this with the equal mocks. The test Client will not register hit for the second mock and the second mock will be executed at N+1 time.
For example, if you try to send 5 requests with this mocks and log response codes:
$builder = new PockBuilder();
$builder->matchHost('example.com')->at(2)->reply(200);
$builder->matchHost('example.com')->at(4)->reply(201);
$builder->always()->reply(400);
You will get this: 400, 400, 200, 400, 400, 201 Instead of this: 400, 400, 200, 400, 201, 400
Parameters
- $hit : int
Return values
selfgetClient()
Create the PSR-18 and HTTPlug client after closing the current definition.
public
getClient() : Client
$client = $pock->getClient();
$response = $client->sendRequest($request);
Return values
ClientgetSymfonyClient()
Returns a Symfony HTTP client backed by the configured mocks.
public
getSymfonyClient() : HttpClientInterface
Installing symfony/http-client is required to call this method.
$response = $pock->getSymfonyClient()->request('GET', 'https://api.example.com/users');
Return values
HttpClientInterfacejsonDecode()
json_decode which throws exception on error.
public
static jsonDecode(string $json[, bool $associative = false ][, int $depth = 512 ][, int $flags = 0 ]) : mixed
Parameters
- $json : string
- $associative : bool = false
- $depth : int = 512
- $flags : int = 0
Tags
matchBody()
Match entire request body.
public
matchBody(StreamInterface|resource|string $data) : self
$pock->matchBody('raw request body');
Parameters
- $data : StreamInterface|resource|string
Return values
selfmatchBodyRegExp()
Match entire request body using provided regular expression.
public
matchBodyRegExp(string $expression[, int $flags = 0 ]) : self
$pock->matchBodyRegExp('~^event:\d+$~');
Parameters
- $expression : string
- $flags : int = 0
Return values
selfmatchCallback()
Match request using provided callback. Callback should receive RequestInterface and return boolean.
public
matchCallback(callable $callback) : self
If returned value is true then request is matched.
$pock->matchCallback(static function (RequestInterface $request) {
return 'internal' === $request->getHeaderLine('X-Caller');
});
Parameters
- $callback : callable
-
Callable that accepts PSR-7 RequestInterface as it's first argument.
Return values
selfmatchExactFormData()
Match request with form-data. Additional fields aren't allowed.
public
matchExactFormData(array<string, mixed> $formFields) : self
$pock->matchExactFormData(['name' => 'Jane', 'active' => '1']);
Parameters
- $formFields : array<string, mixed>
Return values
selfmatchExactHeader()
Matches request by the exact header pattern or values.
public
matchExactHeader(string $header, string|array<string|int, string> $value) : self
$pock->matchExactHeader('Accept', ['application/json', 'text/plain']);
Parameters
- $header : string
- $value : string|array<string|int, string>
Return values
selfmatchExactHeaders()
Matches request by headers values or several values.
public
matchExactHeaders(array<string, string|array<string|int, string>> $headers) : self
Note: only host header will be dropped. Any other headers will not be excluded and can result in the problems with the exact matching.
$pock->matchExactHeaders(['Authorization' => 'Bearer secret']);
Parameters
- $headers : array<string, string|array<string|int, string>>
Return values
selfmatchExactQuery()
Match request by its query. Additional query parameters aren't allowed.
public
matchExactQuery(array<string, mixed> $query) : self
$pock->matchExactQuery(['page' => 2, 'limit' => 20]);
Parameters
- $query : array<string, mixed>
Return values
selfmatchFormData()
Match request with form-data.
public
matchFormData(array<string, mixed> $formFields) : self
Additional fields are allowed.
$pock->matchFormData(['name' => 'Jane']);
Parameters
- $formFields : array<string, mixed>
Return values
selfmatchHeader()
Matches request by header value or several values. Header can have other values which are not specified here.
public
matchHeader(string $header, string|array<string|int, string> $value) : self
Parameters
- $header : string
- $value : string|array<string|int, string>
Tags
Return values
selfmatchHeaderLine()
Matches request by the unparsed header line.
public
matchHeaderLine(string $header, string $value) : self
$pock->matchHeaderLine('Accept', 'application/json, text/plain');
Parameters
- $header : string
- $value : string
Return values
selfmatchHeaderLineRegexp()
Matches request by the unparsed header line using provided regular expression.
public
matchHeaderLineRegexp(string $header, string $pattern) : self
$pock->matchHeaderLineRegexp('Authorization', '~^Bearer [A-Za-z0-9._-]+$~');
Parameters
- $header : string
- $pattern : string
Return values
selfmatchHeaders()
Matches request by headers values or several values. Headers can have other values which are not specified here.
public
matchHeaders(array<string, string|array<string|int, string>> $headers) : self
Parameters
- $headers : array<string, string|array<string|int, string>>
Tags
Return values
selfmatchHost()
Matches request by hostname.
public
matchHost(string $host) : self
$pock->matchHost('api.example.com');
Parameters
- $host : string
Return values
selfmatchJsonBody()
Match JSON request body.
public
matchJsonBody(mixed $data) : self
PHP values are serialized before their decoded JSON structure is compared.
$pock->matchJsonBody(['name' => 'Jane', 'active' => true]);
Parameters
- $data : mixed
Tags
Return values
selfmatchMethod()
Match request by its method.
public
matchMethod(string $method) : self
$pock->matchMethod(RequestMethod::POST);
Parameters
- $method : string
Return values
selfmatchMultipartFormData()
Match request multipart form data. Will not match the request if body is not multipart.
public
matchMultipartFormData(callable $callback) : self
Uses third-party library to parse the data.
$pock->matchMultipartFormData(static function (StreamedPart $part) {
return 'avatar' === $part->getName();
});
Parameters
- $callback : callable
-
Accepts Riverline\MultiPartParser\StreamedPart as an argument, returns true if matched.
Tags
Return values
selfmatchOrigin()
Matches request by origin.
public
matchOrigin(string $origin) : self
The scheme, host, and explicit port found in the origin become separate matchers.
$pock->matchOrigin('https://api.example.com:8443');
Parameters
- $origin : string
Tags
Return values
selfmatchPath()
Match request by its path. Path with and without slash at the start will be treated as the same path.
public
matchPath(string $path) : self
It's not the same for the path with slash at the end of it.
$pock->matchPath('/v1/users');
Parameters
- $path : string
Return values
selfmatchPathRegExp()
Match request by its path using regular expression. This matcher doesn't care about prefix slash since it's pretty easy to do it using regular expression.
public
matchPathRegExp(string $expression[, int $flags = 0 ]) : self
$pock->matchPathRegExp('~^/users/\d+$~');
Parameters
- $expression : string
- $flags : int = 0
Return values
selfmatchPort()
Matches request by the port.
public
matchPort(int $port) : self
$pock->matchPort(8443);
Parameters
- $port : int
Return values
selfmatchQuery()
Match request by its query. Request can contain other query variables.
public
matchQuery(array<string, mixed> $query) : self
Parameters
- $query : array<string, mixed>
Tags
Return values
selfmatchQueryRegExp()
Match request by its query using regular expression.
public
matchQueryRegExp(string $expression[, int $flags = 0 ]) : self
$pock->matchQueryRegExp('~(^|&)page=\d+(&|$)~');
Parameters
- $expression : string
- $flags : int = 0
Return values
selfmatchScheme()
Match request by its scheme.
public
matchScheme(string $scheme) : self
$pock->matchScheme(RequestScheme::HTTPS);
Parameters
- $scheme : string
Return values
selfmatchSerializedJsonBody()
Match JSON request body against JSON string or array with data.
public
matchSerializedJsonBody(array<int|string, mixed>|string $data) : self
$pock->matchSerializedJsonBody('{"name":"Jane"}');
Parameters
- $data : array<int|string, mixed>|string
Tags
Return values
selfmatchSerializedXmlBody()
Match XML request body.
public
matchSerializedXmlBody(string|array<string|int, mixed>|object $data) : self
This method will try to use available XML serializer before matching.
$pock->matchSerializedXmlBody(new CreateUser('Jane'));
Parameters
- $data : string|array<string|int, mixed>|object
Tags
Return values
selfmatchUri()
Matches request by the whole URI.
public
matchUri(UriInterface|string $uri) : self
$pock->matchUri('https://api.example.com/users?page=2');
Parameters
- $uri : UriInterface|string
Return values
selfmatchUriRegExp()
Matches request by the whole URI using regular expression.
public
matchUriRegExp(string $expression[, int $flags = 0 ]) : self
$pock->matchUriRegExp('~^https://api\.example\.com/users/\d+$~');
Parameters
- $expression : string
- $flags : int = 0
Return values
selfmatchXmlBody()
Match XML request body using raw XML data.
public
matchXmlBody(DOMDocument|StreamInterface|resource|string $data) : self
Note: this method will fallback to the string comparison if ext-xsl is not available. It also doesn't serializer values with available XML serializer. Use PockBuilder::matchSerializedXmlBody if you want to execute available serializer.
$pock->matchXmlBody('<user><name>Jane</name></user>');
Parameters
- $data : DOMDocument|StreamInterface|resource|string
Tags
Return values
selfrepeat()
Repeat this mock provided amount of times.
public
repeat(int $hits) : self
For example, if you pass 2 as an argument mock will be able to handle two identical requests.
$pock->matchPath('/retry')->repeat(3)->reply(503);
Parameters
- $hits : int
Return values
selfreply()
Start or update a static response and return its fluent response builder.
public
reply([int $statusCode = 200 ]) : PockResponseBuilder
$pock->matchPath('/users')->reply(200)->withJson(['users' => []]);
Parameters
- $statusCode : int = 200
Return values
PockResponseBuilderreplyWith()
Reply to the request with the provided response.
public
replyWith(ResponseInterface $response) : void
$pock->matchPath('/empty')->replyWith($psr17Factory->createResponse(204));
Parameters
- $response : ResponseInterface
replyWithCallback()
Construct the response during request execution using provided callback.
public
replyWithCallback(callable $callback) : void
Callback should receive the same parameters as in the ReplyFactoryInterface::createReply method.
$pock->matchPath('/echo')->replyWithCallback(
static function (RequestInterface $request, PockResponseBuilder $response) {
return $response->withBody((string) $request->getBody())->getResponse();
}
);
Parameters
- $callback : callable
Tags
replyWithClient()
Reply to the request using provided client. Can be used to send real network request.
public
replyWithClient(ClientInterface $client) : void
$pock->matchHost('sandbox.example.com')->replyWithClient($realClient);
Parameters
- $client : ClientInterface
Tags
replyWithFactory()
Construct the response during request execution using a ReplyFactoryInterface implementation.
public
replyWithFactory(ReplyFactoryInterface $factory) : void
$pock->matchPath('/dynamic')->replyWithFactory(new ProjectReplyFactory());
Parameters
- $factory : ReplyFactoryInterface
Tags
reset()
Resets the builder.
public
reset() : self
$pock->reset()->matchUri('https://api.example.com/new-test')->reply(200);
Return values
selfsetFallbackClient()
Sets fallback Client. It will be used if no request can be matched.
public
setFallbackClient([ClientInterface|null $fallbackClient = null ]) : self
$pock->setFallbackClient($realClient);
Parameters
- $fallbackClient : ClientInterface|null = null
Return values
selfthrowClientException()
Throw a ClientExceptionInterface instance with specified message.
public
throwClientException([string $message = 'Pock ClientException' ]) : self
$pock->matchPath('/invalid')->throwClientException('Client failure');
Parameters
- $message : string = 'Pock ClientException'
Return values
selfthrowException()
Throw an exception when request is being sent.
public
throwException(Throwable $throwable) : self
$pock->matchPath('/broken')->throwException(new RuntimeException('Failure'));
Parameters
- $throwable : Throwable
Return values
selfthrowNetworkException()
Throw a NetworkExceptionInterface instance with specified message.
public
throwNetworkException([string $message = 'Pock NetworkException' ]) : self
$pock->matchPath('/offline')->throwNetworkException('Connection refused');
Parameters
- $message : string = 'Pock NetworkException'
Return values
selfthrowRequestException()
Throw a RequestExceptionInterface instance with specified message.
public
throwRequestException([string $message = 'Pock RequestException' ]) : self
$pock->matchPath('/rejected')->throwRequestException('Invalid request');
Parameters
- $message : string = 'Pock RequestException'