我正在尝试找到一种方法来测试必须存在的匹配/不匹配值的抽象类常量。例如:
// to be extended by ExternalSDKClild
abstract class ExternalSDK {
const VERSION = '3.1.1.';
}
class foo extends AController {
public function init() {
if ( ExternalSDK::VERSION !== '3.1.1' ) {
throw new Exception('Wrong ExternalSDK version!');
}
$this->setExternalSDKChild(new ExternalSDKChild());
}
}
限制...我们使用的框架不允许init()方法中的依赖注入。 (重构init()方法的建议可能是......)
我运行的单元测试和代码覆盖率,涵盖除异常之外的所有内容。我无法找到使ExternalSDK :: Version与它不同的方法。
欢迎所有的想法
答案 0 :(得分:0)
首先,将对new
的调用重构为一个单独的方法。
其次,添加一个获取版本的方法,而不是直接访问常量。 PHP中的类常量在解析时被编译到文件中,并且无法更改。*由于它们是静态访问的,因此无法在不使用相同名称的不同类声明的情况下覆盖它。使用标准PHP的唯一方法是在一个非常昂贵的单独过程中运行测试。
class ExternalSDK {
const VERSION = '3.1.1';
public function getVersion() {
return static::VERSION;
}
}
class foo extends AController {
public function init() {
$sdk = $this->createSDK();
if ( $sdk->getVersion() !== '3.1.1' ) {
throw new Exception('Wrong ExternalSDK version!');
}
$this->setExternalSDKChild($sdk);
}
public function createSDK() {
return new ExternalSDKChild();
}
}
现在进行单元测试。
class NewerSDK extends ExternalSDK {
const VERSION = '3.1.2';
}
/**
* @expectedException Exception
*/
function testInitFailsWhenVersionIsDifferent() {
$sdk = new NewerSDK();
$foo = $this->getMock('foo', array('createSDK'));
$foo->expects($this->once())
->method('createSDK')
->will($this->returnValue($sdk));
$foo->init();
}
* Runkit提供runkit_constant_redefine()
,可以在此处使用。您需要手动捕获异常而不是使用@expectedException
,以便将常量重置为正确的值。或者你可以在tearDown()
中完成。
function testInitFailsWhenVersionIsDifferent() {
try {
runkit_constant_redefine('ExternalSDK::VERSION', '3.1.0');
$foo = new foo();
$foo->init();
$failed = true;
}
catch (Exception $e) {
$failed = false;
}
runkit_constant_redefine('ExternalSDK::VERSION', '3.1.1');
if ($failed) {
self::fail('Failed to detect incorrect SDK version.');
}
}