Skip to content

Instantly share code, notes, and snippets.

@ezzatron
Created August 15, 2011 05:42
Show Gist options
  • Save ezzatron/1145760 to your computer and use it in GitHub Desktop.
Save ezzatron/1145760 to your computer and use it in GitHub Desktop.
Difficult situation: mocking immutable PHP objects with final constructors.
<?php
// Example of how the Primitive class is extended
class Boolean extends Primitive
{
public function assert($value)
{
if (!is_bool($value)) throw new InvalidArgumentException;
}
}
<?php
/*
The idea of the Primitive class is that the value passed to it is absolutely guaranteed to
be of the correct type, and can never be changed (without resorting to extreme measures).
In other words it is 'immutable'.
When testing the Primitive class, I want to verify that assert() is called when the object
is constructed. This is not easy because of the final keyword, but removing it would destroy
that 'immutable' quality of the class.
*/
abstract class Primitive
{
final public function __construct($value)
{
$this->assert($value);
$this->value = $value;
}
final public function value()
{
return $this->value;
}
abstract public function assert($value);
private $value;
}
<?php
// Example PHPUnit test case
class PrimitiveTest extends PHPUnit_Framework_TestCase
{
public function testConstructor()
{
$primitive = $this->getMock('Primitive', array('assert'), array(), '', false);
$primitive->expects($this->once())->method('assert')->with('foo');
$primitive->__construct('foo');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment