Skip to content

Instantly share code, notes, and snippets.

@cjsaylor
Created November 22, 2012 14:36
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cjsaylor/4131481 to your computer and use it in GitHub Desktop.
Save cjsaylor/4131481 to your computer and use it in GitHub Desktop.
Convenient PHPUnit mocking of Singleton Classes
<?php
class Sample {
public __construct() {
}
public function sayHello($name) {
return Someclass::getInstance()->hello($name);
}
}
<?php
class SampleTest extends \PHPUnit_Framework_TestCase {
public function testSayHello() {
$sample = new Sample();
$name = 'Chris';
$replace = 'Goodbye, Chris!';
SomeclassMock::expects($name, $replace);
$this->assertEquals("Goodbye, Chris!", $sample->sayHello($name));
SomeclassMock::cleanup();
}
}
<?php
class Someclass {
protected static $self;
protected __construct() {
}
public static function getInstance() {
if (empty(static::$self)) {
static::$self = new Someclass();
}
return static::$self;
}
public function hello($name) {
return "hello, $name!";
}
}
<?php
class SomeclassMock {
/**
* Generates a mock object on the singleton Someclass util object.
*
* @param array $name
* @return void
*/
public static function expects($name, $replace) {
// Mock the object
$mock = \PHPUnit_Framework_MockObject_Generator::getMock(
'Someclass',
array('hello'),
array(),
'',
false
);
// Replace protected self reference with mock object
$ref = new \ReflectionProperty('Someclass', 'self');
$ref->setAccessible(true);
$ref->setValue(null, $mock);
// Set expectations and return values
$mock
->expects(new \PHPUnit_Framework_MockObject_Matcher_InvokedCount(1))
->method('hello')
->with(
\PHPUnit_Framework_Assert::equalTo($name)
)
->will(new \PHPUnit_Framework_MockObject_Stub_Return($replace));
}
public static function cleanup() {
$ref = new \ReflectionProperty('Someclass', 'self');
$ref->setAccessible(true);
$ref->setValue(null, null);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment