聞こえないJavaエンジニアが適当に書き連ねていく

つらつらとメモしたり日頃の溜まっている想いを吐き出す場所です。

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になった模様。

うまくいったもの

仕方ないので再度調べ直したら、以下のサイトがヒットした。

sebastiankoltun-blog.com

ここに書かれていることを参考に、書き直したら日時を固定できるようになった。

現在日時を返すだけの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");

    }
}

他に参考にしたサイト

qiita.com