PHP の標準関数のスタブする方法はないか探していたところ runkit というものが見つかりました。機能が強力であるため黒魔術的な紹介をされていることが多いのですが、現実というのは残酷なもので黒魔術に頼らないといけない場面もあるのではないかなと思います。
例えば下記のように time()
が直接埋め込まれたメソッドがあったとします。現在のタイムスタンプが指定の値を超えていたら true
、超えていなかったら false
を返すメソッドです。
Event.php
<?php
class Event{
public function isFinished(){
if(1404408309 <= time()){
return true;
}else{
return false;
}
}
}
既に存在するコードに手を入れずにテストを行えるようにするため、テストコード側で runkit の runkit_function_redefine
関数を使って time()
が固定値を返すようにします。意図した固定値を返させるようにすることで、true
と false
のどちらのパターンも一応テストできるようになりました。
EventTest.php
<?php
require_once 'Event.php';
class EventTest extends PHPUnit_Framework_TestCase{
public function testIsClosedReturnsTrue(){
runkit_function_redefine('time', '', 'return 1404410000;');
$event = new Event();
$this->assertTrue($event->isFinished());
}
public function testIsClosedReturnsFalse(){
runkit_function_redefine('time', '', 'return 1404400000;');
$event = new Event();
$this->assertFalse($event->isFinished());
}
}