Last active
August 15, 2019 12:19
-
-
Save ukolka/8448362 to your computer and use it in GitHub Desktop.
PHPUnit extension for testing code that's using PHP's http:// stream wrapper context to make requests.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace tests\unittests\custom; | |
/** | |
* Whenever PHP HTTP stream is used you can | |
* inject a mock stream resource into an object that | |
* expect it. | |
* | |
* Usage example: | |
* | |
* ... | |
* $stream = getMockStream('{"foo": "bar"}'); | |
* $dependency->expects($this->all()) | |
* ->method('getStream') | |
* ->will($this->returnValue($stream)); | |
* $dependent->setDependency($dependency); | |
* ... | |
* | |
* @link http://www.php.net/manual/en/book.stream.php | |
* @author Mykola Bespaliuk | |
*/ | |
abstract class HttpStreamWrapperTestCase extends \PHPUnit_Framework_TestCase { | |
public function setUp() { | |
parent::setUp(); | |
stream_wrapper_unregister('http'); | |
stream_wrapper_register( | |
'http', | |
'tests\unittests\custom\MockHttpStreamWrapper' | |
) or die('Failed to register protocol'); | |
} | |
/** | |
* Makes a mock stream that returns expected values. | |
* @param string $data response body | |
* @param string $code HTTP response code | |
*/ | |
public function getMockStream($data, $code='HTTP/1.1 200 OK') { | |
MockHttpStreamWrapper::$mockBodyData = $data; | |
MockHttpStreamWrapper::$mockResponseCode = $code; | |
$context = stream_context_create( | |
array( | |
'http' => array( | |
'method' => 'GET' | |
) | |
) | |
); | |
$stream = fopen('http://example.com', 'r', false, $context); | |
return $stream; | |
} | |
public function tearDown() { | |
stream_wrapper_restore('http'); | |
} | |
} | |
/** | |
* Class MockHttpStreamWrapper | |
* Stunt double of the PHP HTTP stream wrapper. | |
* @author Mykola Bespaliuk | |
*/ | |
class MockHttpStreamWrapper implements | |
\IteratorAggregate, \ArrayAccess, \Countable{ | |
/** | |
* Using static properties here because it's easy to set them up | |
* before running request and in stream_open method corresponding | |
* object properties are overridden with the | |
* contents of the static properties here. | |
*/ | |
public static $mockBodyData = ''; | |
public static $mockResponseCode = 'HTTP/1.1 200 OK'; | |
public $context; | |
public $position = 0; | |
public $bodyData = 'test body data'; | |
public $responseCode = ''; | |
/** | |
* @var array $foo | |
* Example: | |
* array( | |
* 0 => 'HTTP/1.0 301 Moved Permantenly', | |
* 1 => 'Cache-Control: no-cache', | |
* 2 => 'Connection: close', | |
* 3 => 'Location: http://example.com/foo.jpg', | |
* 4 => 'HTTP/1.1 200 OK', | |
* ... | |
*/ | |
protected $foo = array(); | |
/* IteratorAggregate */ | |
public function getIterator() { | |
return new \ArrayIterator($this->foo); | |
} | |
/* ArrayAccess */ | |
public function offsetExists($offset) { | |
return array_key_exists($offset, $this->foo); | |
} | |
public function offsetGet($offset ) { | |
return $this->foo[$offset]; | |
} | |
public function offsetSet($offset, $value) { | |
$this->foo[$offset] = $value; | |
} | |
public function offsetUnset($offset) { | |
unset($this->foo[$offset]); | |
} | |
/* Countable */ | |
public function count() { | |
return count($this->foo); | |
} | |
/* StreamWrapper */ | |
public function stream_open($path, $mode, $options, &$opened_path) { | |
$this->bodyData = self::$mockBodyData; | |
$this->responseCode = self::$mockResponseCode; | |
array_push($this->foo, self::$mockResponseCode); | |
return true; | |
} | |
public function stream_read($count) { | |
if ($this->position > strlen($this->bodyData)) { | |
return false; | |
} | |
$result = substr($this->bodyData, $this->position, $count); | |
$this->position += $count; | |
return $result; | |
} | |
public function stream_eof() { | |
return $this->position >= strlen($this->bodyData); | |
} | |
public function stream_stat() { | |
return array('wrapper_data' => array('test')); | |
} | |
public function stream_tell() { | |
return $this->position; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment