用cron进行单元测试

时间:2020-06-04 13:01:44

标签: java spring-boot

我需要测试是否在每个午夜执行以下计划的方法:

public class CacheService {

  /** Evicts token from the cache at midnight */
  @Scheduled(cron = "0 0 0 * * *", zone = "Europe/London")
  @CacheEvict(value = CacheConfig.AUTH_TOKEN, allEntries = true)
  public void clearCacheAtMidnight() {
    log.info("Scheduled cache clean at: " + Instant.now());
  }
}

我正在使用以下单元测试:

@SpringBootTest
class CacheServiceTest {

  @SpyBean private CacheService cacheService;

  @Test
  void shouldClearCacheAtMidnight() {
    Instant.now(Clock.fixed(Instant.parse("2020-01-01T00:00:00Z"), ZoneId.of("Europe/London")));
    await()
            .atMost(Duration.ofMinutes(1))
            .untilAsserted(() -> verify(cacheService, atLeast(1)).clearCacheAtMidnight());
  }
}

但不是喜悦。如果我从cron更改为fixrate,则效果很好。 我感觉到我没有正确覆盖系统时钟,或者我没有正确使用设置的间隔。

有任何线索吗?

1 个答案:

答案 0 :(得分:1)

Spring在内部使用MONTH来解析cron表达式以找出下一个触发时间。如果要测试是否正确设置了cron表达式,则可以引用它们的test case并编写自己的表达式,例如:

CronSequenceGenerator

我同意一些测试人员在测试框架时不会建议这样做,但是我肯定会包括它,因为它编写起来很简单,至少我将更加确信我的cron表达式配置正确,尤其是有时候我们需要设置一些非平凡的cron表达式。