【Java】JUnitでDateクラスの日付をMock化する方法

Javaでnew Date()をすると現在時刻が取得できますが、JUnitでテストする対象のクラスにこのnew Date()があると毎回値が変わってしまって厄介ですよね。

この記事では、JUnitを動かした際にnew Date()の値を固定とする方法を紹介していきます。

今回の方法はJUnit4で検証しています。

[スポンサーリンク]

テスト対象のクラス

今回テストする対象のクラスはこちらです。
new Date()の値を返却するメソッドがテスト対象となります。
これだとJUnitを動かすたびに実行結果が変わってきてしまいますよね。。

public class DateLogic {

    public Date getDate() {
        Date date = new Date();
        return date;
    }

}

PowerMockitoのdependency

今回はnew Date()を固定値とするため、JUnitでPowerMockitoを使っていきます。
pom.xmlへこちらのdependencyを追加してPowerMockitoが使えるようにしましょう。

<!-- https://mvnrepository.com/artifact/org.powermock/powermock-module-junit4 -->
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>1.6.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.powermock/powermock-api-mockito -->
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito</artifactId>
    <version>1.6.6</version>
</dependency>

JUnitを使ったテスト

では、new Date()を固定値とするためのJUnitを公開していきます。

package jp.co.example;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import jp.co.example.mock.DateLogic;

@RunWith(PowerMockRunner.class)
@PrepareForTest({DateLogic.class, Date.class})
public class DateMockTest {

    @Test
    public void DateTest() throws Exception {
        SimpleDateFormat sdf =
                new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
        Calendar cal = Calendar.getInstance();
        cal.set(2017, 4, 22, 10, 10, 10);
   
        DateLogic logic = new DateLogic();
        PowerMockito.whenNew(Date.class).withNoArguments().thenReturn(cal.getTime());
        Date result = logic.getDate();

        System.out.println("Date : "+ sdf.format(result));
        assertThat(sdf.format(result), is(sdf.format(cal.getTime())));
    }
}

27行目が一番重要です。
ここでnew Date()の値が常に固定(24行目で設定した値)になるように設定しています。

16行目はテスト対象のクラスと、Dateクラスを定義しましょう。

じつは、JUnitでモック化するには、Mockitoというものもありますが、こちらのライブラリだとnewインスタンスしている箇所やstaticメソッドを使っているところをモック化することができません。

それらをカバーしているのがPowerMockitoです。便利ですね。

Javaのバージョン

今回検証したjavaのバージョンは8です。
JUnitはバージョン4です。

さいごに

new Date()が固定値にできればJUnitでのテストも読みやすく、そして書きやすくなると思います。

ちなみに、CalendarクラスでもPowerMockitoを使えば同じように日付を固定にすることができます。

Calendarクラスでの日付固定化はコチラの記事で解説しています。

今回の方法を流用して、実行時に毎回値が変わるような箇所は全て固定値を指定することができますので、色々工夫して使ってみて下さい。便利ですよ。

それでは!