mirror of
https://github.com/Neur0toxine/pock.git
synced 2025-01-31 04:51:42 +03:00
at(N)
, always()
methods, separate PSR-18 exceptions, throw methods for them, roadmap to stable
This commit is contained in:
parent
03fc4e4c2a
commit
21021e5d70
@ -112,12 +112,11 @@ In order to use unsupported serializer you should create a decorator which imple
|
|||||||
|
|
||||||
# Roadmap to stable
|
# Roadmap to stable
|
||||||
|
|
||||||
- [ ] `at(N)` - execute mock only at Nth call.
|
- [x] `at(N)` - execute mock only at Nth call.
|
||||||
- [ ] `after(N)` - allow mock execution only after Nth call (for using with repeat or always).
|
- [x] `always()` - always execute this mock (removes mock expiration).
|
||||||
- [ ] `always()` - always execute this mock (removes mock expiration).
|
|
||||||
- [ ] Regexp matchers for body, query and path.
|
- [ ] Regexp matchers for body, query and path.
|
||||||
- [ ] Separate `UniversalMockException` into several exceptions (`PockClientException`, `PockNetworkException`, etc).
|
- [x] Separate `UniversalMockException` into several exceptions (`PockClientException`, `PockNetworkException`, etc).
|
||||||
- [ ] Add methods for easier throwing of exceptions listed in previous entry.
|
- [x] Add methods for easier throwing of exceptions listed in previous entry.
|
||||||
- [ ] `replyCallback` - reply using specified callback.
|
- [ ] `replyCallback` - reply using specified callback.
|
||||||
- [ ] `replyFactory` - reply using specified response factory (provide corresponding interface).
|
- [ ] `replyFactory` - reply using specified response factory (provide corresponding interface).
|
||||||
- [ ] Compare XML bodies using `DOMDocument`, fallback to text comparison in case of problems.
|
- [ ] Compare XML bodies using `DOMDocument`, fallback to text comparison in case of problems.
|
||||||
|
10
phpmd.xml
10
phpmd.xml
@ -10,7 +10,15 @@
|
|||||||
<rule ref="rulesets/design.xml" />
|
<rule ref="rulesets/design.xml" />
|
||||||
<rule ref="rulesets/cleancode.xml" />
|
<rule ref="rulesets/cleancode.xml" />
|
||||||
<rule ref="rulesets/codesize.xml" />
|
<rule ref="rulesets/codesize.xml" />
|
||||||
<rule ref="rulesets/naming.xml" />
|
<rule ref="rulesets/naming.xml">
|
||||||
|
<exclude name="ShortMethodName" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule ref="rulesets/naming.xml/ShortMethodName">
|
||||||
|
<properties>
|
||||||
|
<property name="minimum" value="2" />
|
||||||
|
</properties>
|
||||||
|
</rule>
|
||||||
|
|
||||||
<exclude-pattern>tests/*</exclude-pattern>
|
<exclude-pattern>tests/*</exclude-pattern>
|
||||||
</ruleset>
|
</ruleset>
|
||||||
|
@ -74,17 +74,19 @@ class Client implements ClientInterface, HttpClient, HttpAsyncClient
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($mock->getMatcher()->matches($request)) {
|
if ($mock->matches($request)) {
|
||||||
if (null !== $mock->getResponse()) {
|
if (null !== $mock->getResponse()) {
|
||||||
$mock->registerHit();
|
$mock->registerHit();
|
||||||
|
|
||||||
return new HttpFulfilledPromise($mock->getResponse());
|
return new HttpFulfilledPromise($mock->getResponse());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $mock->getThrowable()) {
|
$throwable = $mock->getThrowable($request);
|
||||||
|
|
||||||
|
if (null !== $throwable) {
|
||||||
$mock->registerHit();
|
$mock->registerHit();
|
||||||
|
|
||||||
return new HttpRejectedPromise($mock->getThrowable());
|
return new HttpRejectedPromise($throwable);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IncompleteMockException($mock);
|
throw new IncompleteMockException($mock);
|
||||||
|
45
src/Exception/AbstractRequestAwareException.php
Normal file
45
src/Exception/AbstractRequestAwareException.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PHP 7.3
|
||||||
|
*
|
||||||
|
* @category AbstractRequestAwareException
|
||||||
|
* @package Pock\Exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Pock\Exception;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use Psr\Http\Message\RequestInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class AbstractRequestAwareException
|
||||||
|
*
|
||||||
|
* @category AbstractRequestAwareException
|
||||||
|
* @package Pock\Exception
|
||||||
|
*/
|
||||||
|
class AbstractRequestAwareException extends Exception
|
||||||
|
{
|
||||||
|
/** @var RequestInterface */
|
||||||
|
private $request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Psr\Http\Message\RequestInterface $request
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setRequest(RequestInterface $request): self
|
||||||
|
{
|
||||||
|
$instance = new static($this->message, $this->code, $this->getPrevious()); // @phpstan-ignore-line
|
||||||
|
$instance->request = $request;
|
||||||
|
return $instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Psr\Http\Message\RequestInterface
|
||||||
|
*/
|
||||||
|
public function getRequest(): RequestInterface
|
||||||
|
{
|
||||||
|
return $this->request;
|
||||||
|
}
|
||||||
|
}
|
23
src/Exception/PockClientException.php
Normal file
23
src/Exception/PockClientException.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PHP 7.3
|
||||||
|
*
|
||||||
|
* @category PockClientException
|
||||||
|
* @package Pock\Exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Pock\Exception;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use Psr\Http\Client\ClientExceptionInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PockClientException
|
||||||
|
*
|
||||||
|
* @category PockClientException
|
||||||
|
* @package Pock\Exception
|
||||||
|
*/
|
||||||
|
class PockClientException extends Exception implements ClientExceptionInterface
|
||||||
|
{
|
||||||
|
}
|
22
src/Exception/PockNetworkException.php
Normal file
22
src/Exception/PockNetworkException.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PHP 7.3
|
||||||
|
*
|
||||||
|
* @category PockNetworkException
|
||||||
|
* @package Pock\Exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Pock\Exception;
|
||||||
|
|
||||||
|
use Psr\Http\Client\NetworkExceptionInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PockNetworkException
|
||||||
|
*
|
||||||
|
* @category PockNetworkException
|
||||||
|
* @package Pock\Exception
|
||||||
|
*/
|
||||||
|
class PockNetworkException extends AbstractRequestAwareException implements NetworkExceptionInterface
|
||||||
|
{
|
||||||
|
}
|
22
src/Exception/PockRequestException.php
Normal file
22
src/Exception/PockRequestException.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PHP 7.3
|
||||||
|
*
|
||||||
|
* @category PockRequestException
|
||||||
|
* @package Pock\Exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Pock\Exception;
|
||||||
|
|
||||||
|
use Psr\Http\Client\RequestExceptionInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class PockRequestException
|
||||||
|
*
|
||||||
|
* @category PockRequestException
|
||||||
|
* @package Pock\Exception
|
||||||
|
*/
|
||||||
|
class PockRequestException extends AbstractRequestAwareException implements RequestExceptionInterface
|
||||||
|
{
|
||||||
|
}
|
@ -1,51 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PHP 7.2
|
|
||||||
*
|
|
||||||
* @category UniversalMockException
|
|
||||||
* @package Pock\Exception
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Pock\Exception;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use Psr\Http\Client\ClientExceptionInterface;
|
|
||||||
use Psr\Http\Client\NetworkExceptionInterface;
|
|
||||||
use Psr\Http\Client\RequestExceptionInterface;
|
|
||||||
use Psr\Http\Message\RequestInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class UniversalMockException
|
|
||||||
*
|
|
||||||
* @category UniversalMockException
|
|
||||||
* @package Pock\Exception
|
|
||||||
*/
|
|
||||||
class UniversalMockException extends Exception implements
|
|
||||||
ClientExceptionInterface,
|
|
||||||
NetworkExceptionInterface,
|
|
||||||
RequestExceptionInterface
|
|
||||||
{
|
|
||||||
/** @var mixed */
|
|
||||||
private $request;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UniversalMockException constructor.
|
|
||||||
*
|
|
||||||
* @param mixed $request
|
|
||||||
*/
|
|
||||||
public function __construct($request)
|
|
||||||
{
|
|
||||||
parent::__construct('Default mock exception');
|
|
||||||
|
|
||||||
$this->request = $request;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function getRequest(): RequestInterface
|
|
||||||
{
|
|
||||||
return $this->request;
|
|
||||||
}
|
|
||||||
}
|
|
46
src/Mock.php
46
src/Mock.php
@ -9,7 +9,12 @@
|
|||||||
|
|
||||||
namespace Pock;
|
namespace Pock;
|
||||||
|
|
||||||
|
use Pock\Exception\PockNetworkException;
|
||||||
|
use Pock\Exception\PockRequestException;
|
||||||
use Pock\Matchers\RequestMatcherInterface;
|
use Pock\Matchers\RequestMatcherInterface;
|
||||||
|
use Psr\Http\Client\NetworkExceptionInterface;
|
||||||
|
use Psr\Http\Client\RequestExceptionInterface;
|
||||||
|
use Psr\Http\Message\RequestInterface;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
@ -36,6 +41,9 @@ class Mock implements MockInterface
|
|||||||
/** @var int */
|
/** @var int */
|
||||||
private $maxHits;
|
private $maxHits;
|
||||||
|
|
||||||
|
/** @var int */
|
||||||
|
private $matchAt;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mock constructor.
|
* Mock constructor.
|
||||||
*
|
*
|
||||||
@ -43,18 +51,25 @@ class Mock implements MockInterface
|
|||||||
* @param \Psr\Http\Message\ResponseInterface|null $response
|
* @param \Psr\Http\Message\ResponseInterface|null $response
|
||||||
* @param \Throwable|null $throwable
|
* @param \Throwable|null $throwable
|
||||||
* @param int $maxHits
|
* @param int $maxHits
|
||||||
|
* @param int $matchAt
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
RequestMatcherInterface $matcher,
|
RequestMatcherInterface $matcher,
|
||||||
?ResponseInterface $response,
|
?ResponseInterface $response,
|
||||||
?Throwable $throwable,
|
?Throwable $throwable,
|
||||||
int $maxHits
|
int $maxHits,
|
||||||
|
int $matchAt
|
||||||
) {
|
) {
|
||||||
$this->matcher = $matcher;
|
$this->matcher = $matcher;
|
||||||
$this->response = $response;
|
$this->response = $response;
|
||||||
$this->throwable = $throwable;
|
$this->throwable = $throwable;
|
||||||
|
$this->matchAt = $matchAt;
|
||||||
$this->maxHits = $maxHits;
|
$this->maxHits = $maxHits;
|
||||||
$this->hits = 0;
|
$this->hits = 0;
|
||||||
|
|
||||||
|
if ($this->maxHits < ($matchAt + 1) && -1 !== $this->maxHits) {
|
||||||
|
$this->maxHits = $matchAt + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,7 +77,10 @@ class Mock implements MockInterface
|
|||||||
*/
|
*/
|
||||||
public function registerHit(): MockInterface
|
public function registerHit(): MockInterface
|
||||||
{
|
{
|
||||||
++$this->hits;
|
if (-1 !== $this->maxHits) {
|
||||||
|
++$this->hits;
|
||||||
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,15 +89,27 @@ class Mock implements MockInterface
|
|||||||
*/
|
*/
|
||||||
public function available(): bool
|
public function available(): bool
|
||||||
{
|
{
|
||||||
return $this->hits < $this->maxHits;
|
return -1 === $this->maxHits || $this->hits < $this->maxHits;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getMatcher(): RequestMatcherInterface
|
public function matches(RequestInterface $request): bool
|
||||||
{
|
{
|
||||||
return $this->matcher;
|
if ($this->matcher->matches($request)) {
|
||||||
|
if ($this->matchAt <= 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->matchAt === $this->hits) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->registerHit();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -101,8 +131,12 @@ class Mock implements MockInterface
|
|||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
public function getThrowable(): ?Throwable
|
public function getThrowable(RequestInterface $request): ?Throwable
|
||||||
{
|
{
|
||||||
|
if ($this->throwable instanceof PockRequestException || $this->throwable instanceof PockNetworkException) {
|
||||||
|
return $this->throwable->setRequest($request);
|
||||||
|
}
|
||||||
|
|
||||||
return $this->throwable;
|
return $this->throwable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
namespace Pock;
|
namespace Pock;
|
||||||
|
|
||||||
use Pock\Matchers\RequestMatcherInterface;
|
use Pock\Matchers\RequestMatcherInterface;
|
||||||
|
use Psr\Http\Message\RequestInterface;
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
@ -36,11 +37,14 @@ interface MockInterface
|
|||||||
public function available(): bool;
|
public function available(): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns matcher for the request.
|
* Returns true if underlying matcher has matched provided request.
|
||||||
|
* It also returns false if matcher has matched request but hits condition is not met yet.
|
||||||
*
|
*
|
||||||
* @return \Pock\Matchers\RequestMatcherInterface
|
* @param \Psr\Http\Message\RequestInterface $request
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function getMatcher(): RequestMatcherInterface;
|
public function matches(RequestInterface $request): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns response which should be used as mock data.
|
* Returns response which should be used as mock data.
|
||||||
@ -52,7 +56,9 @@ interface MockInterface
|
|||||||
/**
|
/**
|
||||||
* Returns the throwable which will be thrown as mock data.
|
* Returns the throwable which will be thrown as mock data.
|
||||||
*
|
*
|
||||||
|
* @param \Psr\Http\Message\RequestInterface $request This request may be set into exception if possible
|
||||||
|
*
|
||||||
* @return \Throwable|null
|
* @return \Throwable|null
|
||||||
*/
|
*/
|
||||||
public function getThrowable(): ?Throwable;
|
public function getThrowable(RequestInterface $request): ?Throwable;
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,9 @@ namespace Pock;
|
|||||||
use Diff\ArrayComparer\StrictArrayComparer;
|
use Diff\ArrayComparer\StrictArrayComparer;
|
||||||
use Pock\Enum\RequestMethod;
|
use Pock\Enum\RequestMethod;
|
||||||
use Pock\Enum\RequestScheme;
|
use Pock\Enum\RequestScheme;
|
||||||
|
use Pock\Exception\PockClientException;
|
||||||
|
use Pock\Exception\PockNetworkException;
|
||||||
|
use Pock\Exception\PockRequestException;
|
||||||
use Pock\Matchers\AnyRequestMatcher;
|
use Pock\Matchers\AnyRequestMatcher;
|
||||||
use Pock\Matchers\BodyMatcher;
|
use Pock\Matchers\BodyMatcher;
|
||||||
use Pock\Matchers\CallbackRequestMatcher;
|
use Pock\Matchers\CallbackRequestMatcher;
|
||||||
@ -45,6 +48,7 @@ use Throwable;
|
|||||||
*
|
*
|
||||||
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
||||||
* @SuppressWarnings(PHPMD.TooManyPublicMethods)
|
* @SuppressWarnings(PHPMD.TooManyPublicMethods)
|
||||||
|
* @SuppressWarnings(PHPMD.TooManyMethods)
|
||||||
*/
|
*/
|
||||||
class PockBuilder
|
class PockBuilder
|
||||||
{
|
{
|
||||||
@ -64,6 +68,9 @@ class PockBuilder
|
|||||||
/** @var int */
|
/** @var int */
|
||||||
private $maxHits;
|
private $maxHits;
|
||||||
|
|
||||||
|
/** @var int */
|
||||||
|
private $matchAt;
|
||||||
|
|
||||||
/** @var \Pock\MockInterface[] */
|
/** @var \Pock\MockInterface[] */
|
||||||
private $mocks;
|
private $mocks;
|
||||||
|
|
||||||
@ -329,6 +336,8 @@ class PockBuilder
|
|||||||
*/
|
*/
|
||||||
public function repeat(int $hits): self
|
public function repeat(int $hits): self
|
||||||
{
|
{
|
||||||
|
$this->closePrevious();
|
||||||
|
|
||||||
if ($hits > 0) {
|
if ($hits > 0) {
|
||||||
$this->maxHits = $hits;
|
$this->maxHits = $hits;
|
||||||
}
|
}
|
||||||
@ -336,6 +345,49 @@ class PockBuilder
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Always execute this mock if matched. Mock with this call will not be expired ever.
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function always(): self
|
||||||
|
{
|
||||||
|
$this->closePrevious();
|
||||||
|
$this->maxHits = -1;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Match request only at Nth hit. Previous matches will not be executed.
|
||||||
|
*
|
||||||
|
* **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:
|
||||||
|
* ```php
|
||||||
|
* $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
|
||||||
|
*
|
||||||
|
* @param int $hit
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function at(int $hit): self
|
||||||
|
{
|
||||||
|
$this->closePrevious();
|
||||||
|
$this->matchAt = $hit - 1;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Throw an exception when request is being sent.
|
* Throw an exception when request is being sent.
|
||||||
*
|
*
|
||||||
@ -350,6 +402,42 @@ class PockBuilder
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throw an ClientExceptionInterface instance with specified message
|
||||||
|
*
|
||||||
|
* @param string $message
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function throwClientException(string $message = 'Pock ClientException'): self
|
||||||
|
{
|
||||||
|
return $this->throwException(new PockClientException($message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throw an NetworkExceptionInterface instance with specified message
|
||||||
|
*
|
||||||
|
* @param string $message
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function throwNetworkException(string $message = 'Pock NetworkException'): self
|
||||||
|
{
|
||||||
|
return $this->throwException(new PockNetworkException($message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throw an RequestExceptionInterface instance with specified message
|
||||||
|
*
|
||||||
|
* @param string $message
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function throwRequestException(string $message = 'Pock RequestException'): self
|
||||||
|
{
|
||||||
|
return $this->throwException(new PockRequestException($message));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $statusCode
|
* @param int $statusCode
|
||||||
*
|
*
|
||||||
@ -377,6 +465,7 @@ class PockBuilder
|
|||||||
$this->responseBuilder = null;
|
$this->responseBuilder = null;
|
||||||
$this->throwable = null;
|
$this->throwable = null;
|
||||||
$this->maxHits = 1;
|
$this->maxHits = 1;
|
||||||
|
$this->matchAt = -1;
|
||||||
$this->mocks = [];
|
$this->mocks = [];
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
@ -421,12 +510,14 @@ class PockBuilder
|
|||||||
$this->matcher,
|
$this->matcher,
|
||||||
$response,
|
$response,
|
||||||
$this->throwable,
|
$this->throwable,
|
||||||
$this->maxHits
|
$this->maxHits,
|
||||||
|
$this->matchAt
|
||||||
);
|
);
|
||||||
$this->matcher = new MultipleMatcher();
|
$this->matcher = new MultipleMatcher();
|
||||||
$this->responseBuilder = null;
|
$this->responseBuilder = null;
|
||||||
$this->throwable = null;
|
$this->throwable = null;
|
||||||
$this->maxHits = 1;
|
$this->maxHits = 1;
|
||||||
|
$this->matchAt = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,14 +11,14 @@ namespace Pock\Tests;
|
|||||||
|
|
||||||
use Pock\Enum\RequestMethod;
|
use Pock\Enum\RequestMethod;
|
||||||
use Pock\Enum\RequestScheme;
|
use Pock\Enum\RequestScheme;
|
||||||
use Pock\Exception\UniversalMockException;
|
|
||||||
use Pock\Exception\UnsupportedRequestException;
|
use Pock\Exception\UnsupportedRequestException;
|
||||||
use Pock\PockBuilder;
|
use Pock\PockBuilder;
|
||||||
use Pock\TestUtils\PockTestCase;
|
use Pock\TestUtils\PockTestCase;
|
||||||
use Pock\TestUtils\SimpleObject;
|
use Pock\TestUtils\SimpleObject;
|
||||||
use Psr\Http\Client\ClientExceptionInterface;
|
use Psr\Http\Client\ClientExceptionInterface;
|
||||||
|
use Psr\Http\Client\NetworkExceptionInterface;
|
||||||
|
use Psr\Http\Client\RequestExceptionInterface;
|
||||||
use Psr\Http\Message\RequestInterface;
|
use Psr\Http\Message\RequestInterface;
|
||||||
use RuntimeException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class PockBuilderTest
|
* Class PockBuilderTest
|
||||||
@ -35,7 +35,7 @@ class PockBuilderTest extends PockTestCase
|
|||||||
->createRequest(RequestMethod::GET, self::TEST_URI));
|
->createRequest(RequestMethod::GET, self::TEST_URI));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testThrowException(): void
|
public function testThrowClientException(): void
|
||||||
{
|
{
|
||||||
$this->expectException(ClientExceptionInterface::class);
|
$this->expectException(ClientExceptionInterface::class);
|
||||||
|
|
||||||
@ -43,7 +43,37 @@ class PockBuilderTest extends PockTestCase
|
|||||||
$builder->matchMethod(RequestMethod::GET)
|
$builder->matchMethod(RequestMethod::GET)
|
||||||
->matchScheme(RequestScheme::HTTPS)
|
->matchScheme(RequestScheme::HTTPS)
|
||||||
->matchHost(self::TEST_HOST)
|
->matchHost(self::TEST_HOST)
|
||||||
->throwException(new UniversalMockException('Boom!'));
|
->throwClientException();
|
||||||
|
|
||||||
|
$builder->getClient()->sendRequest(
|
||||||
|
self::getPsr17Factory()->createRequest(RequestMethod::GET, self::TEST_URI)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testThrowNetworkException(): void
|
||||||
|
{
|
||||||
|
$this->expectException(NetworkExceptionInterface::class);
|
||||||
|
|
||||||
|
$builder = new PockBuilder();
|
||||||
|
$builder->matchMethod(RequestMethod::GET)
|
||||||
|
->matchScheme(RequestScheme::HTTPS)
|
||||||
|
->matchHost(self::TEST_HOST)
|
||||||
|
->throwNetworkException();
|
||||||
|
|
||||||
|
$builder->getClient()->sendRequest(
|
||||||
|
self::getPsr17Factory()->createRequest(RequestMethod::GET, self::TEST_URI)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testThrowRequestException(): void
|
||||||
|
{
|
||||||
|
$this->expectException(RequestExceptionInterface::class);
|
||||||
|
|
||||||
|
$builder = new PockBuilder();
|
||||||
|
$builder->matchMethod(RequestMethod::GET)
|
||||||
|
->matchScheme(RequestScheme::HTTPS)
|
||||||
|
->matchHost(self::TEST_HOST)
|
||||||
|
->throwRequestException();
|
||||||
|
|
||||||
$builder->getClient()->sendRequest(
|
$builder->getClient()->sendRequest(
|
||||||
self::getPsr17Factory()->createRequest(RequestMethod::GET, self::TEST_URI)
|
self::getPsr17Factory()->createRequest(RequestMethod::GET, self::TEST_URI)
|
||||||
@ -511,4 +541,50 @@ EOF;
|
|||||||
);
|
);
|
||||||
self::assertEquals('Second token (post)', $response->getBody()->getContents());
|
self::assertEquals('Second token (post)', $response->getBody()->getContents());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testAlways(): void
|
||||||
|
{
|
||||||
|
$builder = new PockBuilder();
|
||||||
|
$builder->matchMethod(RequestMethod::GET)
|
||||||
|
->matchUri(self::TEST_URI)
|
||||||
|
->always()
|
||||||
|
->reply(200)
|
||||||
|
->withHeader('Content-Type', 'text/plain')
|
||||||
|
->withBody('Successful');
|
||||||
|
|
||||||
|
for ($i = 0; $i < 10; $i++) {
|
||||||
|
$response = $builder->getClient()->sendRequest(
|
||||||
|
self::getPsr17Factory()->createRequest(RequestMethod::GET, self::TEST_URI)
|
||||||
|
);
|
||||||
|
|
||||||
|
self::assertEquals(200, $response->getStatusCode());
|
||||||
|
self::assertEquals(['Content-Type' => ['text/plain']], $response->getHeaders());
|
||||||
|
self::assertEquals('Successful', $response->getBody()->getContents());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAt(): void
|
||||||
|
{
|
||||||
|
$builder = new PockBuilder();
|
||||||
|
$builder->matchMethod(RequestMethod::GET)
|
||||||
|
->matchUri(self::TEST_URI)
|
||||||
|
->at(2)
|
||||||
|
->reply(200);
|
||||||
|
|
||||||
|
$builder->matchMethod(RequestMethod::GET)
|
||||||
|
->matchUri(self::TEST_URI)
|
||||||
|
->at(4)
|
||||||
|
->reply(201);
|
||||||
|
|
||||||
|
$builder->always()->reply(400);
|
||||||
|
$builder->getClient();
|
||||||
|
|
||||||
|
for ($i = 0; $i < 5; $i++) {
|
||||||
|
$response = $builder->getClient()->sendRequest(
|
||||||
|
self::getPsr17Factory()->createRequest(RequestMethod::GET, self::TEST_URI)
|
||||||
|
);
|
||||||
|
|
||||||
|
self::assertEquals(1 === $i ? 200 : (4 === $i ? 201 : 400), $response->getStatusCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user