web-dev-qa-db-ja.com

春に@Scheduledをテストする

Springでは、注釈を使用して特定の間隔でタスクをスケジュールおよび実行することができます。 @Scheduled

この動作を単体テストする便利な方法はありますか?

もちろん、Beanのメソッドを自分で呼び出すこともできますが、 設定ミスによる複数の実行 などの問題が発生しないようにする必要があります。

他のフレームワークでは、自分で時間を早めることができます。 1つの例は、 Activiti で呼び出すことができます

org.activiti.engine.impl.util.ClockUtil.setCurrentTime(date)

フレームワークが使用する時間を早送りします。

春に匹敵するものはありますか?

基本的に私がやりたいことは、単体テストでこのようなことです(SpringJUnit4ClassRunner

@Test public void testTaskScheduling() {

  assertThat(someOtherBean.getSomeProperty(), is(equalTo(whatIinitiallyExpect)));

  SpringClockUtil.setDate(dateInTwoHours)// This is what I am missing
  SpringTaskExecutor.executeAllScheduledTasks() // Also missing

  assertThat(someOtherBean.getSomeProperty(), is(equalTo(whatIexpectNow)));
}
45
David

通常のJUnitを使用して実際のメソッドの実行をテストできますが、指定した@Scheduled(cron = "0 * * * * *")が正しいかどうかをテストするには、次を使用できます。

@Test
public void testScheduler(){
    // to test if a cron expression runs only from Monday to Friday
    org.springframework.scheduling.support.CronTrigger trigger = 
                                      new CronTrigger("0 0 1 * * MON-FRI");
    Calendar today = Calendar.getInstance();
    today.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);

    SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss EEEE"); 
    final Date yesterday = today.getTime();
    log.info("Yesterday was : " + df.format(yesterday));
    Date nextExecutionTime = trigger.nextExecutionTime(
        new TriggerContext() {

            @Override
            public Date lastScheduledExecutionTime() {
                return yesterday;
            }

            @Override
            public Date lastActualExecutionTime() {
                return yesterday;
            }

            @Override
            public Date lastCompletionTime() {
                return yesterday;
            }
        });

    String message = "Next Execution date: " + df.format(nextExecutionTime);
    log.info(message);

}

出力は次のとおりです。

Yesterday was : 2015/11/06 11:41:58 Friday

Next Execution date: 2015/11/09 01:00:00 Monday

最後の実行(TriggerContextで設定)は金曜日であったため、次の実行は次の月曜日になります。

私はSpring APIをいじっていましたが、この解決策を見つけました。これが私を助けてくれるので、誰かの助けになることを願っています。

36
Fernando Abreu