Spring Boot 2.0.6で日時を固定したテストを書きたいとき
断り書き
個人的な覚書です。 バージョンアップで動かなくなる可能性があるので検索でヒットして、真似る時は気を付けてください。
前提
以下に書かれている記述が動いた時のバージョンは以下の通り。
- Java 1.8
- Spring boot 2.0.6
- JUnit Platform 1.3.1
- JUnit Jupiter 5.1.1 (Spring boot のtesterデフォルト)
- JUnit Vintage 5.1.1 (Spring boot のtesterデフォルト)
- Jmockit 1.43
やりたいこと
プログラム内で行っている、システム日付取得の部分をJUnitでのテストの時は固定の日時にしたい。 ※時間に応じて挙動が変わる個所があるため。
試したこと
ダメだったもの
最初はここに書かれている内容を真似して書いたらうまくいった。
JMockit を使用して LocalDateTime.now() で指定した日時を取得する. · GitHub
しかし、実はJmockitのバージョンがかなり古いものを使っていた。(どこかの記述をコピペしたのが原因)
諸事情でIDEを変えた時に、JMockitのバージョンも上げたら java.lang.ExceptionInInitializerError を吐いてしまった…。
調べると、JMockitのバージョンアップで今まで書けていた内容がNGになった模様。
うまくいったもの
仕方ないので再度調べ直したら、以下のサイトがヒットした。
ここに書かれていることを参考に、書き直したら日時を固定できるようになった。
現在日時を返すだけのfactoryクラスを作る。
import java.time.LocalDateTime; import org.springframework.stereotype.Component; @Component public class TimeFactory { public LocalDateTime now() { return LocalDateTime.now(); } }
呼び出す側は、TimeFactory.java をインジェクションする。
import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import org.springframework.stereotype.Component; @Component public class TimeFactoryCall { private TimeFactory clock; public TimeFactoryCall(TimeFactory factory) { this.clock = factory; } public String get() { LocalDateTime date = clock.now(); return date.format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss")); } }
テストプログラムはこんな感じ。
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.when; import java.time.LocalDateTime; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.junit.jupiter.SpringExtension; @ExtendWith(SpringExtension.class) @SpringBootTest class TimeFactoryCallTest { @MockBean private TimeFactory clock; @Test void test() { LocalDateTime TEST = LocalDateTime.of(2018, 10, 16, 14, 23, 59); when(clock.now()).thenReturn(TEST); TimeFactoryCall call = new TimeFactoryCall(clock); assertEquals(call.get(), "2018/10/16 14:23:59"); } }