2010-11-19 10 views
16

ユニットテストの日付操作クラスの現在の時刻(つまり、時間()の出力)をPHPで変更するにはどうすればよいですか?ユニットテストの日付関数の現在時刻をPHPで変更する方法

+0

http://stackoverflow.com/questions/530649/is-it-possible-to-replace-monkeypatch-php-functions –

+0

いくつかのコードを表示できますか?私の意見では、単体テストのために 'time()'をオーバーライドする必要がある場合、*テストやコードに何らかの問題があるかもしれません。 – netcoder

+0

クラスは現在の日付を操作します。私はちょうどすべての日付のすべてのメソッドの単語を正しく確認したい。 – happytoad

答えて

3

はあなたの日付操作クラスから

+0

私はテストのためだけにクラスのロジックを変更する必要がありますか? – happytoad

+1

@happytoad - 日付操作クラスの 'time()'の呼び出しを、あなたが制御しているものに置き換える必要はありません。たとえば、パラメータとしてテストする関数に時間値を渡すことも、日付クラスのコンストラクタに渡すこともできます。 – rojoca

+1

ですので、時間を変更する方法はありません。現在の時刻を変更するなどの簡単なことはテストに利用できないというのは奇妙です。バマー。ありがとう。 – happytoad

3

time()の依存関係を削除する必要があるように私の推測では、あなたの依存関係で苦労されていますね。単体テストでは、あなたの時間を提供するメソッド/クラスの出力を確実に制御したいのですが、クラス内でtime()関数を使用しているようです。私はあなたの時間を提供し、あなたの単体テストに模擬したTimeクラスを作成すると言うでしょう。

5

私は最近、PHP 5.3の名前空間を使用している場合に最適なソリューションを考え出しました。現在の名前空間内に新しいtime()関数を実装し、テストで戻り値を設定する共有リソースを作成することができます。その後、time()への不適格な呼び出しでは、新しい関数が使用されます。さらに読書のために

私はあなたがインターフェイスベースの継承モデル検討するかもしれない私のblog

+1

私は最近、 'time()'のような非決定的なPHP関数をモックするためにその言語機能を使用するライブラリ[php-mock](https://github.com/malkusch/php-mock)を実装しました。 –

3

で詳細にそれを説明:現在の時間で作業する必要が独自のクラスを取るだろう

interface iClock 
{ 
    public function getTime(); 

} 

class SystemClock implements iClock 
{ 
    public function getTime() 
    { 
     return time(); 
    } 
} 

class FakeClock implements iClock 
{ 
    private $time; 

    function __construct($time) 
    { 
     $this->time = $time; 
    } 

    public function getTime() 
    { 
     return $this->time; 
    } 

    // you could have more functions to advance the time, etc. 
} 

iClockインターフェイスタイプのコンストラクタパラメータ

class YourOwnClass 
{ 
    private $clock; 

    function __construct(iClock $clock) 
    { 
     $this->clock = $clock; 
    } 

    function someFunction() 
    { 
     $now = $this->clock->getTime(); 

     // whatever 
     return $now; 
    } 
} 

その後、あなたは、単に時計の種類を注入でしょう、あなたはユニットテストにあったかどうかに応じて、望んでいた:

$realWorldInstance = new YourOwnClass(new SystemClock()); 
echo $realWorldInstance->someFunction(); 
$unitTestInstance = new YourOwnClass(new FakeClock(1234)); 
echo $unitTestInstance->someFunction(); 

をところで - 私は、多くの場合、このパターンを使用します.NETでも同様です。 Noda Timeによって提供されるIClockインターフェイスにも組み込まれています。このパターンがPHPではうまくいかない理由はありません。整数のタイムスタンプではなく、DateTimeを返すこともできますが、上記はパターンを使用するために必要な最小値です。

関連する問題