2
namespace GuzzleHttp\Subscriber;
4
use GuzzleHttp\Event\RequestEvents;
5
use GuzzleHttp\Event\SubscriberInterface;
6
use GuzzleHttp\Event\BeforeEvent;
7
use GuzzleHttp\Exception\RequestException;
8
use GuzzleHttp\Message\MessageFactory;
9
use GuzzleHttp\Message\ResponseInterface;
10
use GuzzleHttp\Stream\StreamInterface;
13
* Queues mock responses or exceptions and delivers mock responses or
14
* exceptions in a fifo order.
16
class Mock implements SubscriberInterface, \Countable
18
/** @var array Array of mock responses / exceptions */
21
/** @var bool Whether or not to consume an entity body when mocking */
24
/** @var MessageFactory */
28
* @param array $items Array of responses or exceptions to queue
29
* @param bool $readBodies Set to false to not consume the entity body of
30
* a request when a mock is served.
32
public function __construct(array $items = [], $readBodies = true)
34
$this->factory = new MessageFactory();
35
$this->readBodies = $readBodies;
36
$this->addMultiple($items);
39
public function getEvents()
41
// Fire the event last, after signing
42
return ['before' => ['onBefore', RequestEvents::SIGN_REQUEST - 10]];
46
* @throws \OutOfBoundsException|\Exception
48
public function onBefore(BeforeEvent $event)
50
if (!$item = array_shift($this->queue)) {
51
throw new \OutOfBoundsException('Mock queue is empty');
52
} elseif ($item instanceof RequestException) {
56
// Emulate reading a response body
57
$request = $event->getRequest();
58
if ($this->readBodies && $request->getBody()) {
59
while (!$request->getBody()->eof()) {
60
$request->getBody()->read(8096);
64
$saveTo = $event->getRequest()->getConfig()->get('save_to');
66
if (null !== $saveTo) {
67
$body = $item->getBody();
69
if (is_resource($saveTo)) {
70
fwrite($saveTo, $body);
71
} elseif (is_string($saveTo)) {
72
file_put_contents($saveTo, $body);
73
} elseif ($saveTo instanceof StreamInterface) {
74
$saveTo->write($body);
78
$event->intercept($item);
81
public function count()
83
return count($this->queue);
87
* Add a response to the end of the queue
89
* @param string|ResponseInterface $response Response or path to response file
92
* @throws \InvalidArgumentException if a string or Response is not passed
94
public function addResponse($response)
96
if (is_string($response)) {
97
$response = file_exists($response)
98
? $this->factory->fromMessage(file_get_contents($response))
99
: $this->factory->fromMessage($response);
100
} elseif (!($response instanceof ResponseInterface)) {
101
throw new \InvalidArgumentException('Response must a message '
102
. 'string, response object, or path to a file');
105
$this->queue[] = $response;
111
* Add an exception to the end of the queue
113
* @param RequestException $e Exception to throw when the request is executed
117
public function addException(RequestException $e)
125
* Add multiple items to the queue
127
* @param array $items Items to add
129
public function addMultiple(array $items)
131
foreach ($items as $item) {
132
if ($item instanceof RequestException) {
133
$this->addException($item);
135
$this->addResponse($item);
143
public function clearQueue()