测试使用带有PHPUnit模拟对象的get_类的代码
使用PHPUnit和一个mock对象,我试图测试一些代码,这些代码使用测试使用带有PHPUnit模拟对象的get_类的代码,php,phpunit,Php,Phpunit,使用PHPUnit和一个mock对象,我试图测试一些代码,这些代码使用get\u class来确定一个对象是否包含在过滤器中 下面是要测试的类: class BlockFilter implements FilterInterface { private $classes; public function __construct(array $classes = array()) { $this->classes = $classes; }
get\u class
来确定一个对象是否包含在过滤器中
下面是要测试的类:
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;
}
}
以下是我的单元测试的方法:
public function testIfContainerBlockIsIncluded()
{
$containerBlock = $this->getMock('Pwn\ContentBundle\Document\ContainerBlock');
$containerBlock->expects($this->any())->method('getDocumentType')->will($this->returnValue(Type::BLOCK));
$filter = new BlockFilter(array('Pwn\ContentBundle\Document\ContainerBlock'));
$this->assertTrue($filter->isIncluded($containerBlock));
}
模拟对象$containerBlock
的行为类似于真实对象Pwn\ContentBundle\Document\containerBlock
;甚至使用instanceof
的代码也能工作(因为我相信PHPUnit使它成为了真实类的一个子类)
正在测试的代码使用get_class
获取类的字符串值,并将其与预期的类名数组进行比较。不幸的是,对于mock对象,get_类返回如下内容:
Mock_ContainerBlock_ac231064
(每次调用时_ac231064后缀都会更改)
这会导致我的测试失败,那么我有什么选择呢
- 重新编写代码以避免使用get_类?这意味着在尝试编写可测试代码时不应使用get_类
- 使用ContainerBlock类的真实实例而不是模拟实例?这意味着我们正在同时有效地测试这两个类
- 你们将要提出的另一个惊人的聪明把戏??)李>
感谢您的帮助…在测试中通过模拟的类名:
new BlockFilter(array(get_class($this->containerBlock)));
好主意,我想这其实是在我的脑海里,但它似乎使测试某种程度上“人造”;我不太可能发现考试本身的错误。所以我现在想知道这是比使用真实对象而不是模拟更好还是更糟…@LarsJ我看不出有任何问题。您的块过滤器正在测试数组中的类名,因此传递模拟的类名完全可以。顺便说一句,我会模拟界面而不是ContainerBlock,因为这就是isIncluded上的TypeHint所要求的;我已经把它付诸实践,效果很好。