Skip to content

Instantly share code, notes, and snippets.

Created March 9, 2011 17:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save anonymous/862553 to your computer and use it in GitHub Desktop.
Save anonymous/862553 to your computer and use it in GitHub Desktop.
Example how to mock stream wrappers
<?php
namespace Jarlssen\PHPUnit;
use PHPUnit_Framework_TestCase as TestCase,
PHPUnit_Framework_MockObject_InvocationMocker as InvocationMocker,
PHPUnit_Framework_MockObject_Invocation_Object as InvocationObject,
ReflectionObject;
/**
* Allows to mock stream wrappers
*
* @example <code>
* class TestCase extends PHPUnit_Framework_TestCase
* {
* function setUp()
* {
* $this->sslWrapper = StreamWrapperMock::setUp('ssl', $this);
* }
*
* function tearDown()
* {
* StreamWrapperMock::tearDown();
* }
*
* function testExample()
* {
* $blob = str_repeat('a', 10000);
* $this->sslWrapper->expects($this->once())
* ->method('stream_open')
* ->will($this->returnValue(true));
* $this->sslWrapper->expects($this->once())
* ->method('stream_read')
* ->will($this->returnValue(substr($blob, 0, 8096)));
* $this->sslWrapper->expects($this->once())
* ->method('stream_close')
* ->will($this->returnValue(false));
* $this->sslWrapper->expects($this->once())
* ->method('stream_write')
* ->with('TEST')
* ->will($this->returnValue(4));
* $r = fopen('ssl://foo', 'rw');
* $this->assertSame(str_repeat('a', 8096), fread($r, 8096));
* fwrite($r, 'TEST');
* }
* }
* </code>
*/
class StreamWrapperMock
{
public $context;
protected static $_registeredProtocols = array();
protected static $_registry = array();
protected $_protocol;
public function __phpunit_verify()
{
self::$_registry[$this->_protocol]['mocker']->verify();
}
public function __phpunit_cleanup()
{
unset(self::$_registry[$this->_protocol]);
}
public function __call($method, array $args)
{
/** No way to find out which protocol this stream wrapper represents until stream_open */
if ($method === 'stream_open') {
$this->_protocol = substr($args[0], 0, strpos($args[0], '://'));
$testCase = self::$_registry[$this->_protocol]['testCase'];
self::$_registry[$this->_protocol]['streamWrapper'] = $this;
if (method_exists($testCase, 'registerMock')) {
$testCase->registerMock($this);
} else {
stream_wrapper_unregister($this->_protocol);
$testCase->markTestSkipped(
'Could not register mock object in this PHPUnit version. '
. 'Method PHPUnit_Framework_TestCase::registerMock() not present'
);
}
$this->__call('__construct', array());
}
return self::$_registry[$this->_protocol]['mocker']->invoke(
new InvocationObject(get_class(), $method, $args, $this)
);
}
public static function setUp($protocol, TestCase $testCase)
{
self::$_registeredProtocols[] = $protocol;
stream_wrapper_register($protocol, get_called_class(), STREAM_IS_URL);
self::$_registry[$protocol] = array(
'mocker' => new InvocationMocker(),
'testCase' => $testCase,
);
return self::$_registry[$protocol]['mocker'];
}
public static function getInstance($protocol)
{
return self::$_registry[$protocol]['streamWrapper'];
}
public static function tearDown()
{
foreach (self::$_registeredProtocols as $protocol) {
if (isset(self::$_registry[$protocol])) {
self::$_registry[$protocol]['mocker']->verify();
}
if (in_array($protocol, stream_get_wrappers())) {
stream_wrapper_unregister($protocol);
}
unset(self::$_registry[$protocol]);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment