Kam*_*zic 6 php phpunit unit-testing destructor mocking
代码将解释一切:
<?php
class ATest extends PHPUnit_Framework_TestCase
{
public function testDestructorOnOriginalClass() {
$a = new A(); // It
unset($a); // works
echo " great!"; // great!
$this->expectOutputString('It works great!');
}
public function testDestructorOnMockedClass() {
$a = $this->getMock('A', array('someNonExistingMethod')); // It
unset($a); // works
echo " great!"; // great!
$this->expectOutputString('It works great!');
}
}
class A {
public function __construct()
{
echo "It";
}
public function __destruct()
{
echo " works";
}
}
Run Code Online (Sandbox Code Playgroud)
和输出:
# phpunit ATest.php
PHPUnit 3.7.13 by Sebastian Bergmann.
.F
Time: 0 seconds, Memory: 3.50Mb
There was 1 failure:
1) ATest::testDestructorOnMockedClass
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'It works great!'
+'It great! works'
FAILURES!
Tests: 2, Assertions: 2, Failures: 1.
Run Code Online (Sandbox Code Playgroud)
正如您在第二次测试中看到的那样,它works以错误的顺序打印,可能是因为phpunit存储了对某个地方的模拟引用并__destruct()在测试结束时被调用...好的我已经检查过getMock()方法并确实存储了对mocked对象的引用($this->mockObjects[] = $mockObject;)有效地阻止对象被破坏,因此__destructor()从未被调用.
/**
* Returns a mock object for the specified class.
*
* @param string $originalClassName
* @param array $methods
* @param array $arguments
* @param string $mockClassName
* @param boolean $callOriginalConstructor
* @param boolean $callOriginalClone
* @param boolean $callAutoload
* @param boolean $cloneArguments
* @return PHPUnit_Framework_MockObject_MockObject
* @throws PHPUnit_Framework_Exception
* @since Method available since Release 3.0.0
*/
public function getMock($originalClassName, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE, $cloneArguments = FALSE)
{
$mockObject = PHPUnit_Framework_MockObject_Generator::getMock(
$originalClassName,
$methods,
$arguments,
$mockClassName,
$callOriginalConstructor,
$callOriginalClone,
$callAutoload,
$cloneArguments
);
$this->mockObjects[] = $mockObject;
return $mockObject;
}
Run Code Online (Sandbox Code Playgroud)
所以问题是 - 有没有办法防止这种情况发生?忽略__destruct()它应该被调用的时候我认为是不好的限制.
您只是取消设置局部变量 - 您没有销毁对象本身。
该对象也由 PHPUnit 本身保存。所以仍然有一个引用,因此你的unset()不会导致__destruct().
因此,当前的行为无法改变。在 phpunit 问题跟踪器中打开一个错误。