Permalink
Browse files

Released version 0.6

  • Loading branch information...
acoulton committed Mar 15, 2012
2 parents a716d62 + 3f20163 commit 85ea4d0d23f2fe5aec64648291fb8f7d3a3cc1ed
View
@@ -0,0 +1,20 @@
+# Mimic for PHP
+#(c) 2012 Andrew Coulton
+# Changelog
+
+## v0.6
+
+### New features
+* Use .md extension for userguide links so that they can be read on github
+(requires latest version of Kohana 3.2 to browse in the userguide module)
+* Provides a base unittest testcase class for common assertions and requirements (see issue #4)
+*
+
+### Bugfixes
+* Explicitly sets Request content-length header if not present - fixes #5
+* Only requires vfsStream to run Mimic's own unit tests - previously caused an
+error if trying to run other testcases in the project without vfsStream installed.
+
+## v0.5
+
+* First version
View
@@ -1,6 +1,6 @@
# Mimic
-**[View builds]((http://travis-ci.org/acoulton/mimic) | master: ![Build status - master branch](https://secure.travis-ci.org/acoulton/mimic.png?branch=master) |
+**[View builds](http://travis-ci.org/acoulton/mimic) | master: ![Build status - master branch](https://secure.travis-ci.org/acoulton/mimic.png?branch=master) |
develop: ![Build Status - develop branch](https://secure.travis-ci.org/acoulton/mimic.png?branch=develop) |
overall: ![Build Status - overall](https://secure.travis-ci.org/acoulton/mimic.png)**
@@ -0,0 +1,163 @@
+<?php
+defined('SYSPATH') or die('No direct script access.');
+
+/**
+ * Base class for test cases that use Mimic to test interaction with external web
+ * services, handling set up and tear down of the Mimic request client and providing
+ * suitable assertions as required.
+ *
+ * @package Mimic
+ * @category TestInterface
+ * @author Andrew Coulton
+ * @copyright (c) 2011 Ingenerator
+ * @license http://kohanaframework.org/license
+ */
+abstract class Mimic_Unittest_Testcase extends Unittest_TestCase
+{
+ /**
+ * The current Mimic instance
+ * @var Mimic
+ */
+ public $mimic = NULL;
+
+ /**
+ * If set, will load a default scenario in setUp
+ * @var string
+ */
+ protected $_mimic_default_scenario = NULL;
+
+ /**
+ * Stores a reference to the Mimic instance, and resets requests for the
+ * next test execution
+ */
+ public function setUp() {
+ parent::setUp();
+ $this->mimic = Mimic::instance();
+ $this->mimic->reset_requests();
+ if ($this->_mimic_default_scenario)
+ {
+ $this->mimic->load_scenario($this->_mimic_default_scenario);
+ }
+ }
+
+ /**
+ * Asserts that an expected number of requests were made
+ * @param integer $expected
+ */
+ public function assertMimicRequestCount($expected)
+ {
+ $this->assertEquals($expected, $this->mimic->request_count());
+ }
+
+ /**
+ * Asserts that the URL of the most recent request is equal to an expected value
+ * @param string $expected
+ */
+ public function assertMimicLastRequestURL($expected)
+ {
+ $this->assertEquals($expected, $this->mimic->last_request()->uri());
+ }
+
+ /**
+ * Asserts that the HTTP request method of the most recent request is equal to
+ * an expected value
+ *
+ * @param string $expected
+ */
+ public function assertMimicLastRequestMethod($expected)
+ {
+ $this->assertEquals($expected, $this->mimic->last_request()->method());
+ }
+
+ /**
+ * Asserts that the most recent request included a header with the given value
+ *
+ * @param string $header The header name
+ * @param string $expected The expected value
+ */
+ public function assertMimicLastRequestHeader($header, $expected)
+ {
+ $this->assertEquals($expected, $this->mimic->last_request()->headers($header));
+ }
+
+ /**
+ * Asserts that the most recent request included an expected $_GET parameter
+ *
+ * @param string $key
+ * @param string $expected
+ */
+ public function assertMimicLastRequestQuery($key, $expected)
+ {
+ $this->assertEquals($expected, $this->mimic->last_request()->query($key));
+ }
+
+ /**
+ * Asserts that the request body of the most recent request was as expected
+ * @param string $expected
+ */
+ public function assertMimicLastRequestBody($expected)
+ {
+ $this->assertEquals($expected, $this->mimic->last_request()->body());
+ }
+
+ /**
+ * Searches the request history for a request to the given URL and (optionally)
+ * with the specified method, returning TRUE or FALSE.
+ *
+ * @param string $url
+ * @param string $method
+ * @return boolean
+ */
+ protected function _search_request_history($url, $method)
+ {
+ foreach ($this->mimic->request_history() as $request)
+ {
+ if (($method !== NULL) AND ($method !== $request->method()))
+ {
+ continue;
+ }
+
+ if ($request->uri() === $url)
+ {
+ return TRUE;
+ }
+ }
+
+ // Nothing found
+ return FALSE;
+
+ }
+
+ /**
+ * Verify that a request (optionally with a specified method) was made to the
+ * given URL at some point in execution - for requests where the sequence doesn't
+ * matter, this is obviously less brittle than asserting a specific request.
+ *
+ * @param string $url
+ * @param string $method
+ */
+ public function assertMimicRequestsContains($url, $method = NULL)
+ {
+ if ( ! $this->_search_request_history($url, $method))
+ {
+ $this->fail("Expected $method request to $url and none was made");
+ }
+ }
+
+ /**
+ * Verify that a request (optionally with a specified method) was not made to
+ * the given URL at any point in execution - for requests where the sequence doesn't
+ * matter, this is obviously less brittle than asserting a specific request.
+ *
+ * @param string $url
+ * @param string $method
+ */
+ public function assertMimicRequestsNotContains($url, $method = NULL)
+ {
+ if ($this->_search_request_history($url, $method))
+ {
+ $this->fail("A $method request was made to $url");
+ }
+ }
+
+}
@@ -33,6 +33,12 @@ class Request_Client_Mimic extends Request_Client_External
*/
public function _send_message(Request $request)
{
+ // Set a content-length if not set already (fixes #5)
+ if ($request->headers('content-length') === NULL)
+ {
+ $request->headers('content-length', (string) strlen($request->body()));
+ }
+
// Create OR retrieve the Mimic and Mimic_Request_Store instances
$mimic = $this->mimic();
$store = $this->store();
@@ -145,4 +151,4 @@ protected function _send_external($request)
return $client->_send_message($request);
}
-} // End Request_Client_Mimic
+} // End Request_Client_Mimic
View
@@ -12,11 +12,11 @@ debug_headers | FALSE | Add X-Mimic debug headers to
enable_recording| FALSE | Allow recording of requests that aren't matched?
enable_updating | FALSE | Update matched requests by executing and storing new response?
external_client | NULL | Specify an external client to use when executing requests - if NULL will use whatever is set for [Request_Client_External]::$client
-response_formatters | array | An array of [formatters](formatters) to use for given content-types
+response_formatters | array | An array of [formatters](formatters.md) to use for given content-types
## Default formatters
-As shipped, Mimic uses the following default [formatters](formatters):
+As shipped, Mimic uses the following default [formatters](formatters.md):
Content-Type | Formatter
-------------------------|------------
@@ -31,4 +31,4 @@ application/rss+xml |[Mimic_Response_Formatter_XML]
* (others) |[Mimic_Response_Formatter]
---
-Continue to [Response Formatters](formatters)
+Continue to [Response Formatters](formatters.md)
@@ -70,7 +70,7 @@ straightforward:
)
)));
-For more on how requests are matched, see [the section on request matching](matching).
+For more on how requests are matched, see [the section on request matching](matching.md).
## Response bodies
@@ -82,10 +82,10 @@ purposes if required. Likewise the same response body can be used by multiple
request definitions (for example, if different response headers are required but
the body is the same).
-Response bodies are stored using [response formatters](formatters) which apply an
+Response bodies are stored using [response formatters](formatters.md) which apply an
appropriate file extension for the content type and can convert the content to a
human readable format (for example, adding newlines and indentation to JSON responses)
for easier editing and verification.
---
-Continue to [Testing with Mimic](testing)
+Continue to [Testing with Mimic](testing.md)
View
@@ -5,12 +5,12 @@ web services.
If you've used the [VCR module for Ruby](https://github.com/myronmarston/vcr),
you'll recognise the concept. By default, [Mimic] intercepts all external requests
-and throws an exception. When [recording mode](recording) is enabled, [Mimic] executes the
+and throws an exception. When [recording mode](recording.md) is enabled, [Mimic] executes the
external request and records the response (complete with headers and response
status) to disk. Future requests to the external resource will return the
response that has been stored on disk, allowing increased performance
and more importantly an idempotent [implementation of unit and functional
-tests](testing) with a minimum of configuration or mocking code.
+tests](testing.md) with a minimum of configuration or mocking code.
## Scenarios
Mimic supports multiple named scenarios (nothing more complex than a separate
@@ -30,13 +30,13 @@ By default, Mimic matches all of:
* URI Parameters
* Request Headers
-However, [matching rules can be easily edited](matching) to allow looser
+However, [matching rules can be easily edited](matching.md) to allow looser
matching of requests which can be useful if you want to return the same response
for multiple requests - for example to minimise the effort involved in supporting
query parameters that aren't relevant to your test scenario.
## Customising responses
-Requests and responses are stored in [easily editable formats](customising),
+Requests and responses are stored in [easily editable formats](customising.md),
allowing you to customise both the request and response for a variety of scenarios.
For example, you might want to edit the response to simulate an error condition that is difficult
to trigger from the client side.
@@ -47,14 +47,14 @@ authentication tokens or private content before committing to a source code
repository!**
Mimic aids review, source control and editing of responses by passing supported
-content types (currently XML and JSON) through a [formatter](formatters) before
+content types (currently XML and JSON) through a [formatter](formatters.md) before
saving. Formatters "pretty-print" the responses, introducing newlines, indentation,
and whitespace to make responses human-readable.
## Verifying application behaviour
In addition to replaying "canned" responses, Mimic keeps a history of requests
executed and responses returned. You can
-[access the history from your test cases](testing#verifying-expectations)
+[access the history from your test cases](testing.md#verifying-expectations)
to verify:
* That an expected pattern of requests were sent (for example, that a given
@@ -68,4 +68,4 @@ to verify:
* PHP 5.3 or greater
If you want to run the unit tests, you will need PHPUnit and the
-[vfsStream](https://github.com/mikey179/vfsStream) virtual filesystem library.
+[vfsStream](https://github.com/mikey179/vfsStream) virtual filesystem library.
View
@@ -131,4 +131,4 @@ wildcards later.
);
---
-Continue to [Customising Responses](customising)
+Continue to [Customising Responses](customising.md)
View
@@ -1,8 +1,8 @@
## [Mimic]()
-- [Recording](recording)
-- [Matching Requests](matching)
-- [Customising Responses](customising)
-- [Testing with Mimic](testing)
-- [Updating definitions](updating)
-- [Configuration](config)
-- [Response Formatters](formatters)
+- [Recording](recording.md)
+- [Matching Requests](matching.md)
+- [Customising Responses](customising.md)
+- [Testing with Mimic](testing.md)
+- [Updating definitions](updating.md)
+- [Configuration](config.md)
+- [Response Formatters](formatters.md)
View
@@ -24,7 +24,7 @@ of the request and the response) and save it to disk for customisation and futur
use.
To use this feature, you'll need to enable recording mode either in your
-[configuration](config) or by setting [Mimic::enable_recording]\(TRUE).
+[configuration](config.md) or by setting [Mimic::enable_recording]\(TRUE).
// Enable recording
Mimic::instance()->enable_recording(TRUE);
@@ -34,4 +34,4 @@ To use this feature, you'll need to enable recording mode either in your
->execute();
---
-Continue to [Matching Requests](matching)
+Continue to [Matching Requests](matching.md)
Oops, something went wrong.

0 comments on commit 85ea4d0

Please sign in to comment.