最近、システム時計を読み出す処理を単体テストにかける仕事が有りまして、みなさんどうしているのかとGoogleで検索してみました。
でも、実際にこうしたという例がほとんど見つからず、あちこち探し回っているうちにこのサイトに行き着きました。
[システムのタイマーをラップしてテスト工数を削減する - Sacrificed](http://d.hatena.ne.jp/cnaos/20100105/1262694743"システムのタイマーをラップしてテスト工数を削減する - Sacrificed")
そこで、このアイディアにしたがって実装してみました。
DateWarpper.java
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
/**
* 単体テスト用のDateラッパー/Date Warpper for Unit Test(JUnit).
* 単にgetInstanceすると、システム時計を内包するインスタンスが取れる。
* シングルトンにしてあるので、どこかの処理で setDate を呼んでやれば、その日付を持ったインスタンスになる。
* @author peki
*
*/
public class DateWarpper
{
/**
* シングルトンインスタンス
*/
private static final DateWarpper instance = new DateWarpper();
/**
* Dateのインスタンス
*/
private Date date = new Date();
/**
* インスタンス取得
* テスト対象からは、システム時刻を取得しているつもり
* @return
*/
public static DateWarpper getInstance()
{
return instance;
}
/**
* 任意の時刻を覚えさせる処理。JUnitのテストケースから使うことを想定している。
* @param dateTime 設定したい時刻。DateTime.parse にそのまま渡す。
* @return DateWapperのインスタンスを返す
* @throws ParseException DateTime.parseが例外を返したときに、そのままthrowする
*/
public static synchronized DateWarpper setDate( String dateTime ) throws ParseException
{
/*
* TODO:重要な日付であれば、特定のサーバーのユーザーしかsetDateできないとか、
* ここで認証処理を書いたほうが良いでしょう。
*/
DateWarpper inst = getInstance();
inst.date = null; // 気休め
if ( dateTime == null )
{
inst.date = new Date();
}
else
{
inst.date = DateFormat.getInstance().parse( dateTime );
}
return instance;
}
/**
* Dateインスタンスの読み出し.
* テスト対象からは、システム時刻を取得しているつもり、テストケースからは任意の時刻を取得させることが出来る。
* @return Dateのインスタンス
*/
public Date getDate()
{
return date;
}
}
こんなものでどうでしょう?
私はJavaを使い始めて一年ほどで、Javaのお作法はあまり知らないのですが、もっといい方法があったりするのでしょうか?