私のテストケースでは、時間に敏感なメソッドをテストする必要があります。そのメソッドでは、Java 8 クラス LocalDate を使用していますが、 Joda ではありません。
テストの実行中に時間を変更するにはどうすればよいですか
私のテストケースでは、時間に敏感なメソッドをテストする必要があります。そのメソッドでは、Java 8 クラス LocalDate を使用していますが、 Joda ではありません。
テストの実行中に時間を変更するにはどうすればよいですか
コードをリファクタリングして、テストしやすいようにすることができます。たとえば、すべての呼び出しLocalDate.now()をカスタムのモック可能な非静的クラスのメソッドの呼び出しに置き換えます。
または、 PowerMock の mockStaticを使用できます。
now() のような静的メソッドをモックする必要がある場合は、PowerMockのような複数の代替手段を使用できます。
@RunWith(PowerMockRunner.class)
@PrepareForTest({ LocalDateTime.class })
public class LocalDateTimeUnitTest {
@Test
public void givenLocalDateTimeMock_whenNow_thenGetFixedLocalDateTime() {
Clock clock = Clock.fixed(Instant.parse("2014-12-22T10:15:30.00Z"), ZoneId.of("UTC"));
LocalDateTime dateTime = LocalDateTime.now(clock);
mockStatic(LocalDateTime.class);
when(LocalDateTime.now()).thenReturn(dateTime);
String dateTimeExpected = "2014-12-22T10:15:30";
LocalDateTime now = LocalDateTime.now();
assertThat(now).isEqualTo(dateTimeExpected);
}
}
またはJMockit、実際に JMockit では MockUp クラスを使用できます。
@Test
public void givenLocalDateTimeWithJMock_whenNow_thenGetFixedLocalDateTime() {
Clock clock = Clock.fixed(Instant.parse("2014-12-21T10:15:30.00Z"), ZoneId.of("UTC"));
new MockUp<LocalDateTime>() {
@Mock
public LocalDateTime now() {
return LocalDateTime.now(clock);
}
};
String dateTimeExpected = "2014-12-21T10:15:30";
LocalDateTime now = LocalDateTime.now();
assertThat(now).isEqualTo(dateTimeExpected);
}
または期待クラス:
@Test
public void givenLocalDateTimeWithExpectations_whenNow_thenGetFixedLocalDateTime() {
Clock clock = Clock.fixed(Instant.parse("2014-12-23T10:15:30.00Z"), ZoneId.of("UTC"));
LocalDateTime dateTimeExpected = LocalDateTime.now(clock);
new Expectations(LocalDateTime.class) {
{
LocalDateTime.now();
result = dateTimeExpected;
}
};
LocalDateTime now = LocalDateTime.now();
assertThat(now).isEqualTo(dateTimeExpected);
}
ここでさらに例を見つけることができます。
もう 1 つの簡単な方法は、固定の Clock インスタンスでnow()メソッドを使用することです。確かに、java.time パッケージのほとんどのクラスには、Clock パラメータを持つ now() メソッドがあります。
@Test
public void givenFixedClock_whenNow_thenGetFixedLocalDateTime() {
Clock clock = Clock.fixed(Instant.parse("2014-12-22T10:15:30.00Z"), ZoneId.of("UTC"));
String dateTimeExpected = "2014-12-22T10:15:30";
LocalDateTime dateTime = LocalDateTime.now(clock);
assertThat(dateTime).isEqualTo(dateTimeExpected);
}
また、さまざまなエンティティやリクエストで一貫性のない「現在」を使用しないように、本番環境で固定クロック (トランザクションの開始時に値が固定される) を渡したい場合もあります。詳細については、この質問を参照してください。
春の使用:
ClockConfiguration クラス:
@Configuration
public class ClockConfiguration {
private final static LocalDate LOCAL_DATE = LocalDate.of(2019, 12, 17);
@Bean
@ConditionalOnMissingBean
Clock getSystemDefaultZoneClock() {
return Clock.systemDefaultZone();
}
@Bean
@Profile("test")
@Primary
Clock getFixedClock() {
return Clock.fixed(LOCAL_DATE.atStartOfDay(ZoneId.systemDefault()).toInstant(), ZoneId.systemDefault());
}
}
SomeService クラス:
@Service
@RequiredArgsConstructor
public class SomeService {
private final Clock clock;
public void someMethod(){
...
LocalDateTime.now(clock)
LocalDate.now(clock)
...
}
}
テストにはアクティブな「テスト」プロファイルが必要です。
SomeServiceTest クラス:
@ActiveProfiles("test")
@EnableConfigurationProperties
@SpringBootTest(classes = [YourAppMainClass])
class SomeServiceTest {
...
}
現在の日付を関数パラメーターとして渡すだけです。
fun doSmthng(now: LocalDate = LocalDate.now()) {
testAnotherService.doSmthng1(TestObj("my message!", now))
}
そしてテストでは、特定の日付を渡してそれをアサートできます。アイデアは、関数本体で明示的に作成する代わりに、依存関係を注入することです。