春季测试@Scheduled

2022-08-31 19:39:32

Spring提供了使用注释以特定时间间隔安排和执行任务的可能性,例如@Scheduled

有没有一种方便的方法来单元测试此行为?

当然,我可以自己调用bean的方法,但我想确保我不会遇到由于配置错误等原因导致多次执行等问题。

其他框架提供了自己快进时间的可能性。一个例子是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)));
}

答案 1

您可以使用常规 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,我找到了这个解决方案,我希望这对某人有所帮助,因为它对我有所帮助。


答案 2

通过直接调用 Bean 来测试调度代码。

然后通过以下方式测试调度配置:

1)在测试环境中部署代码,让它运行一段时间,然后检查日志和/或结果(假设计划的代码做了一些日志记录和/或产生可见的结果)。

2) 使用命名空间在 Spring XML 配置中外部化调度配置,并使用 注入特定于单元测试的间隔/调度(最好是简短且频繁的,以便在单元/集成测试中使用)。然后在测试中验证在给定的(短)时间内,计划的代码(无论是模拟的还是真实的东西)被调用了正确的次数。<task: />PropertyPlaceHolderConfigurer


推荐