3
namespace GuzzleHttp\Subscriber;
5
use GuzzleHttp\Adapter\Transaction;
6
use GuzzleHttp\Event\BeforeEvent;
7
use GuzzleHttp\Event\HeadersEvent;
8
use GuzzleHttp\Event\RequestEvents;
9
use GuzzleHttp\Event\SubscriberInterface;
10
use GuzzleHttp\Exception\RequestException;
11
use GuzzleHttp\Message\MessageFactory;
12
use GuzzleHttp\Message\ResponseInterface;
15
* Queues mock responses or exceptions and delivers mock responses or
16
* exceptions in a fifo order.
18
class Mock implements SubscriberInterface, \Countable
20
/** @var array Array of mock responses / exceptions */
23
/** @var bool Whether or not to consume an entity body when mocking */
26
/** @var MessageFactory */
30
* @param array $items Array of responses or exceptions to queue
31
* @param bool $readBodies Set to false to not consume the entity body of
32
* a request when a mock is served.
34
public function __construct(array $items = [], $readBodies = true)
36
$this->factory = new MessageFactory();
37
$this->readBodies = $readBodies;
38
$this->addMultiple($items);
41
public function getEvents()
43
// Fire the event last, after signing
44
return ['before' => ['onBefore', RequestEvents::SIGN_REQUEST - 10]];
48
* @throws \OutOfBoundsException|\Exception
50
public function onBefore(BeforeEvent $event)
52
if (!$item = array_shift($this->queue)) {
53
throw new \OutOfBoundsException('Mock queue is empty');
54
} elseif ($item instanceof RequestException) {
58
// Emulate the receiving of the response headers
59
$request = $event->getRequest();
60
$transaction = new Transaction($event->getClient(), $request);
61
$transaction->setResponse($item);
62
$request->getEmitter()->emit(
64
new HeadersEvent($transaction)
67
// Emulate reading a response body
68
if ($this->readBodies && $request->getBody()) {
69
while (!$request->getBody()->eof()) {
70
$request->getBody()->read(8096);
74
$event->intercept($item);
77
public function count()
79
return count($this->queue);
83
* Add a response to the end of the queue
85
* @param string|ResponseInterface $response Response or path to response file
88
* @throws \InvalidArgumentException if a string or Response is not passed
90
public function addResponse($response)
92
if (is_string($response)) {
93
$response = file_exists($response)
94
? $this->factory->fromMessage(file_get_contents($response))
95
: $this->factory->fromMessage($response);
96
} elseif (!($response instanceof ResponseInterface)) {
97
throw new \InvalidArgumentException('Response must a message '
98
. 'string, response object, or path to a file');
101
$this->queue[] = $response;
107
* Add an exception to the end of the queue
109
* @param RequestException $e Exception to throw when the request is executed
113
public function addException(RequestException $e)
121
* Add multiple items to the queue
123
* @param array $items Items to add
125
public function addMultiple(array $items)
127
foreach ($items as $item) {
128
if ($item instanceof RequestException) {
129
$this->addException($item);
131
$this->addResponse($item);
139
public function clearQueue()