読者です 読者をやめる 読者になる 読者になる

PHP で時刻に関わるテストをする

時刻に関わるテストの大体は面倒くさい。
次の金曜日のUNIXTIMEを返す関数が来週も正しく動作することをテストしたい場合、以下のようにサーバ時刻を変更し、完了後に元に戻すことでテストができる。

<?php
date_default_timezone_set("Asia/Tokyo");

// 次の金曜日のUNIXTIMEを返す 
function nextFriday() {
    echo strtotime("next Friday");
}

// 1週間後にサーバ時刻を変更
exec("date --set '′date --date \'7 day\'′' ");
// テストを実行
nextFriday();
// ntpdateを利用し時刻を元に戻す
exec("ntpdate ntpd_hostname");

正しく動作はするけど、サーバ時刻をずらすのは大袈裟すぎる。
ntpdateが正しく動作しなかったとき、commit時刻が未来をさしてて大変なことになったりする。

関数の引数にUNIXTIMEを受け取り、初期値をnullとしてnullの場合現在時刻を利用するように実装すると、開発では引数を使わず、テストでは1週間後のUNIXTIMEを渡すことがテストができる。

<?php
date_default_timezone_set("Asia/Tokyo");

// 次の金曜日のUNIXTIMEを返す 
// 引数にUNIXTIMEを取るようにする
function nextFriday($time = null) {
    echo strtotime("next Friday", is_null($time) ? time() : $time);
}

// テストを実行
nextFriday(strtotime("7 days"));

テストがしやすいように実装しようという話。
#よりよい方法を教えてください