Во-первых, реорганизуйте вызов 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.');
}
}