使用带有 PHPUnit 模拟对象的 get_class 测试代码
Using PHPUnit and a mock object, I am trying to test some code that uses get_class
to determine if an object is included by a filter or not.
Here is the class to be tested:
class BlockFilter implements FilterInterface
{
private $classes;
public function __construct(array $classes = array())
{
$this->classes = $classes;
}
public function isIncluded(NodeTraversableInterface $node)
{
if (Type::BLOCK != $node->getDocumentType()) {
return false;
}
if (! empty($this->classes)) {
/*** HERE IS THE PROBLEM: ***/
return in_array(get_class($node), $this->classes);
}
return true;
}
}
Here is the method from my unit test:
public function testIfContainerBlockIsIncluded()
{
$containerBlock = $this->getMock('PwnContentBundleDocumentContainerBlock');
$containerBlock->expects($this->any())->method('getDocumentType')->will($this->returnValue(Type::BLOCK));
$filter = new BlockFilter(array('PwnContentBundleDocumentContainerBlock'));
$this->assertTrue($filter->isIncluded($containerBlock));
}
The mock object $containerBlock
behaves like the real object PwnContentBundleDocumentContainerBlock
; even code using instanceof
works (because PHPUnit makes it a subclass of the real class, I believe).
The code being tested uses get_class
to get a string value of the class and compare it with an array of expected class names. Unfortunately, for the mock object, get_class returns something like this:
Mock_ContainerBlock_ac231064
(the _ac231064 suffix changes on each invocation).
This causes my test to fail, so what are my options?
- Rework the code to avoid using get_class? This implies get_class should not be used when trying to write testable code.
- Use a real instance of the ContainerBlock class instead of a mock? This means we are effectively testing both classes at once.
- Some other awesomely clever trick that you're all going to suggest??? ;)
Thanks for any help...
解决方案Pass the Mock's class name in the test:
new BlockFilter(array(get_class($this->containerBlock)));
相关文章