web-dev-qa-db-fra.com

Test @ prévu au printemps

Spring offre la possibilité de planifier et d'exécuter des tâches à des intervalles spécifiques à l'aide d'annotations, par ex. @Scheduled

Existe-t-il un moyen pratique de tester ce comportement à l'unité?

Bien sûr, je pourrais appeler la méthode du bean moi-même, mais je veux m'assurer de ne pas rencontrer de problèmes comme plusieurs exécutions en raison d'une mauvaise configuration et ainsi de suite.

D'autres cadres offrent la possibilité d'avancer le temps vous-même. Un exemple est Activiti où vous pouvez appeler

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

pour avancer rapidement le temps utilisé par le framework.

Y a-t-il quelque chose de comparable au printemps?

Essentiellement, ce que je veux faire est quelque chose comme ça dans un test unitaire (exécutez en utilisant 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

Vous pouvez tester l'exécution réelle de la méthode à l'aide de la JUnit standard, mais pour tester si la @Scheduled(cron = "0 * * * * *") que vous avez spécifiée est correcte, vous pouvez utiliser:

@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);

}

Voici la sortie:

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

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

Comme la dernière exécution (définie dans le TriggerContext) était un vendredi, la prochaine exécution aura lieu le lundi suivant.

Je jouais avec l'API Spring et j'ai trouvé cette solution, j'espère que ça aide quelqu'un comme ça m'a aidé.

36
Fernando Abreu