~tcuthbert/wordpress/openstack-objectstorage

« back to all changes in this revision

Viewing changes to vendor/guzzlehttp/guzzle/docs/testing.rst

  • Committer: Jacek Nykis
  • Date: 2015-02-11 15:35:31 UTC
  • Revision ID: jacek.nykis@canonical.com-20150211153531-hmy6zi0ov2qfkl0b
Initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
======================
 
2
Testing Guzzle Clients
 
3
======================
 
4
 
 
5
Guzzle provides several tools that will enable you to easily mock the HTTP
 
6
layer without needing to send requests over the internet.
 
7
 
 
8
* Mock subscriber
 
9
* Mock adapter
 
10
* Node.js web server for integration testing
 
11
 
 
12
Mock Subscriber
 
13
===============
 
14
 
 
15
When testing HTTP clients, you often need to simulate specific scenarios like
 
16
returning a successful response, returning an error, or returning specific
 
17
responses in a certain order. Because unit tests need to be predictable, easy
 
18
to bootstrap, and fast, hitting an actual remote API is a test smell.
 
19
 
 
20
Guzzle provides a mock subscriber that can be attached to clients or requests
 
21
that allows you to queue up a list of responses to use rather than hitting a
 
22
remote API.
 
23
 
 
24
.. code-block:: php
 
25
 
 
26
    use GuzzleHttp\Client;
 
27
    use GuzzleHttp\Subscriber\Mock;
 
28
    use GuzzleHttp\Message\Response;
 
29
 
 
30
    $client = new Client();
 
31
 
 
32
    // Create a mock subscriber and queue two responses.
 
33
    $mock = new Mock([
 
34
        new Response(200, ['X-Foo' => 'Bar']),         // Use response object
 
35
        "HTTP/1.1 202 OK\r\nContent-Length: 0\r\n\r\n"  // Use a response string
 
36
    ]);
 
37
 
 
38
    // Add the mock subscriber to the client.
 
39
    $client->getEmitter()->attach($mock);
 
40
    // The first request is intercepted with the first response.
 
41
    echo $client->get('/')->getStatusCode();
 
42
    //> 200
 
43
    // The second request is intercepted with the second response.
 
44
    echo $client->get('/')->getStatusCode();
 
45
    //> 202
 
46
 
 
47
When no more responses are in the queue and a request is sent, an
 
48
``OutOfBoundsException`` is thrown.
 
49
 
 
50
History Subscriber
 
51
==================
 
52
 
 
53
When using things like the ``Mock`` subscriber, you often need to know if the
 
54
requests you expected to send were sent exactly as you intended. While the mock
 
55
subscriber responds with mocked responses, the ``GuzzleHttp\Subscriber\History``
 
56
subscriber maintains a history of the requests that were sent by a client.
 
57
 
 
58
.. code-block:: php
 
59
 
 
60
    use GuzzleHttp\Client;
 
61
    use GuzzleHttp\Subscriber\History;
 
62
 
 
63
    $client = new Client();
 
64
    $history = new History();
 
65
 
 
66
    // Add the history subscriber to the client.
 
67
    $client->getEmitter()->attach($history);
 
68
 
 
69
    $client->get('http://httpbin.org/get');
 
70
    $client->head('http://httpbin.org/get');
 
71
 
 
72
    // Count the number of transactions
 
73
    echo count($history);
 
74
    //> 2
 
75
    // Get the last request
 
76
    $lastRequest = $history->getLastRequest();
 
77
    // Get the last response
 
78
    $lastRequest = $history->getLastResponse();
 
79
 
 
80
    // Iterate over the transactions that were sent
 
81
    foreach ($history as $transaction) {
 
82
        echo $transaction['request']->getMethod();
 
83
        //> GET, HEAD
 
84
        echo $transaction['response']->getStatusCode();
 
85
        //> 200, 200
 
86
    }
 
87
 
 
88
The history subscriber can also be printed, revealing the requests and
 
89
responses that were sent as a string, in order.
 
90
 
 
91
.. code-block:: php
 
92
 
 
93
    echo $history;
 
94
 
 
95
::
 
96
 
 
97
    > GET /get HTTP/1.1
 
98
    Host: httpbin.org
 
99
    User-Agent: Guzzle/4.0-dev curl/7.21.4 PHP/5.5.8
 
100
 
 
101
    < HTTP/1.1 200 OK
 
102
    Access-Control-Allow-Origin: *
 
103
    Content-Type: application/json
 
104
    Date: Tue, 25 Mar 2014 03:53:27 GMT
 
105
    Server: gunicorn/0.17.4
 
106
    Content-Length: 270
 
107
    Connection: keep-alive
 
108
 
 
109
    {
 
110
      "headers": {
 
111
        "Connection": "close",
 
112
        "X-Request-Id": "3d0f7d5c-c937-4394-8248-2b8e03fcccdb",
 
113
        "User-Agent": "Guzzle/4.0-dev curl/7.21.4 PHP/5.5.8",
 
114
        "Host": "httpbin.org"
 
115
      },
 
116
      "origin": "76.104.247.1",
 
117
      "args": {},
 
118
      "url": "http://httpbin.org/get"
 
119
    }
 
120
 
 
121
    > HEAD /get HTTP/1.1
 
122
    Host: httpbin.org
 
123
    User-Agent: Guzzle/4.0-dev curl/7.21.4 PHP/5.5.8
 
124
 
 
125
    < HTTP/1.1 200 OK
 
126
    Access-Control-Allow-Origin: *
 
127
    Content-length: 270
 
128
    Content-Type: application/json
 
129
    Date: Tue, 25 Mar 2014 03:53:27 GMT
 
130
    Server: gunicorn/0.17.4
 
131
    Connection: keep-alive
 
132
 
 
133
Mock Adapter
 
134
============
 
135
 
 
136
In addition to using the Mock subscriber, you can use the
 
137
``GuzzleHttp\Adapter\MockAdapter`` as the adapter of a client to return the
 
138
same response over and over or return the result of a callable function.
 
139
 
 
140
.. code-block:: php
 
141
 
 
142
    use GuzzleHttp\Client;
 
143
    use GuzzleHttp\Adapter\MockAdapter;
 
144
    use GuzzleHttp\Adapter\TransactionInterface;
 
145
    use GuzzleHttp\Message\Response;
 
146
 
 
147
    $mockAdapter = new MockAdapter(function (TransactionInterface $trans) {
 
148
        // You have access to the request
 
149
        $request = $trans->getRequest();
 
150
        // Return a response
 
151
        return new Response(200);
 
152
    });
 
153
 
 
154
    $client = new Client(['adapter' => $mockAdapter]);
 
155
 
 
156
Test Web Server
 
157
===============
 
158
 
 
159
Using mock responses is almost always enough when testing a web service client.
 
160
When implementing custom :doc:`HTTP adapters <adapters>`, you'll need to send
 
161
actual HTTP requests in order to sufficiently test the adapter. However, a
 
162
best practice is to contact a local web server rather than a server over the
 
163
internet.
 
164
 
 
165
- Tests are more reliable
 
166
- Tests do not require a network connection
 
167
- Tests have no external dependencies
 
168
 
 
169
Using the test server
 
170
---------------------
 
171
 
 
172
.. warning::
 
173
 
 
174
    The following functionality is provided to help developers of Guzzle
 
175
    develop HTTP adapters. There is no promise of backwards compatibility
 
176
    when it comes to the node.js test server or the ``GuzzleHttp\Tests\Server``
 
177
    class. If you are using the test server or ``Server`` class outside of
 
178
    guzzlehttp/guzzle, then you will need to configure autoloading and
 
179
    ensure the web server is started manually.
 
180
 
 
181
.. hint::
 
182
 
 
183
    You almost never need to use this test web server. You should only ever
 
184
    consider using it when developing HTTP adapters. The test web server
 
185
    is not necessary for mocking requests. For that, please use the
 
186
    Mock subcribers and History subscriber.
 
187
 
 
188
Guzzle ships with a node.js test server that receives requests and returns
 
189
responses from a queue. The test server exposes a simple API that is used to
 
190
enqueue responses and inspect the requests that it has received.
 
191
 
 
192
Any operation on the ``Server`` object will ensure that
 
193
the server is running and wait until it is able to receive requests before
 
194
returning.
 
195
 
 
196
.. code-block:: php
 
197
 
 
198
    use GuzzleHttp\Client;
 
199
    use GuzzleHttp\Tests\Server;
 
200
 
 
201
    // Start the server and queue a response
 
202
    Server::enqueue("HTTP/1.1 200 OK\r\n\Content-Length: 0r\n\r\n");
 
203
 
 
204
    $client = new Client(['base_url' => Server::$url]);
 
205
    echo $client->get('/foo')->getStatusCode();
 
206
    // 200
 
207
 
 
208
``GuzzleHttp\Tests\Server`` provides a static interface to the test server. You
 
209
can queue an HTTP response or an array of responses by calling
 
210
``Server::enqueue()``. This method accepts a string representing an HTTP
 
211
response message, a ``GuzzleHttp\Message\ResponseInterface``, or an array of
 
212
HTTP message strings / ``GuzzleHttp\Message\ResponseInterface`` objects.
 
213
 
 
214
.. code-block:: php
 
215
 
 
216
    // Queue single response
 
217
    Server::enqueue("HTTP/1.1 200 OK\r\n\Content-Length: 0r\n\r\n");
 
218
 
 
219
    // Clear the queue and queue an array of responses
 
220
    Server::enqueue([
 
221
        "HTTP/1.1 200 OK\r\n\Content-Length: 0r\n\r\n",
 
222
        "HTTP/1.1 404 Not Found\r\n\Content-Length: 0r\n\r\n"
 
223
    ]);
 
224
 
 
225
When a response is queued on the test server, the test server will remove any
 
226
previously queued responses. As the server receives requests, queued responses
 
227
are dequeued and returned to the request. When the queue is empty, the server
 
228
will return a 500 response.
 
229
 
 
230
You can inspect the requests that the server has retrieved by calling
 
231
``Server::received()``. This method accepts an optional ``$hydrate`` parameter
 
232
that specifies if you are retrieving an array of HTTP requests as strings or an
 
233
array of ``GuzzleHttp\Message\RequestInterface`` objects.
 
234
 
 
235
.. code-block:: php
 
236
 
 
237
    foreach (Server::received() as $response) {
 
238
        echo $response;
 
239
    }
 
240
 
 
241
You can clear the list of received requests from the web server using the
 
242
``Server::flush()`` method.
 
243
 
 
244
.. code-block:: php
 
245
 
 
246
    Server::flush();
 
247
    echo count(Server::received());
 
248
    // 0