はい、kawamotoです
blogは書いているとはとても言えないぐらいサボっております。
右も左もわからぬひよっこですので奇をてらわずにTest::名前空間のモジュールの紹介をしようと思います。
Test::MockTime は testの最中に実行される time, localtime, gmtime などの時間に関する関数の振る舞いを書き換える便利なモジュールです。
以下のような症状によく効きます。
使い方はこちらの記事でも説明されていますが、
$ cat ~/test.pl use feature qw( say ); use Test::MockTime qw( :all ); say time; set_absolute_time(0); say "# set_absolute_time(0);"; say time; say "# ----- sleep(2); -----"; sleep 2; say time; say ""; set_fixed_time(0); say "# set_fixed__time(0);"; say time; say "# ----- sleep(2); -----"; sleep 2; say time;
$ perl test.pl 1323183883 # set_absolute_time(0); 0 # ----- sleep(2); ----- 2 # set_fixed__time(0); 0 # ----- sleep(2); ----- 0
こんな感じです。
time, gmtime, localtime の振る舞いが↓のようになります。
注意点としては time() などの関数の書き換えはコンパイルフェーズに行われるので、使う順番を間違えると正しく動かずはまることになります(xaicron++)。
「よくわかんねーぞ」という人は、このモジュールをなるべく早くuseし、BEGIN{} ブロックのなかで set_fixed_time() などを実行するとよいと思います!
あと、普通やらないと思いますがset_fixed_time()とset_absolute_time()を同じコードで使うのは避けたほうがよさそうです(上の例ではやっちゃっていますが)。
ちなみに違うレイヤーの同様のアプローチとして、MySQLで UNIX_TIMESTAMP()などを使っている場合にはテストの時だけSET TIMESTAMPを発行するという手もありますね。
明日は、実はもう書き上がっているという予感のするbayashiさんです。たぶん。