![](/img/trans.png)
[英]Spring-Boot @Scheduled Cron expressions to make slight delay between two tasks?
[英]Test a @Scheduled function in Spring-boot with cron property
我想測試我的 Cron-job 是否會在給定時間(每年 1 月 1 日 00:00)執行。 有沒有辦法測試這個? 不幸的是,我在網上找到的每個示例都指的是將在修復期后執行的作業,例如所有 5 秒。( https://www.baeldung.com/spring-testing-scheduled-annotation )。
@Scheduled(cron = " 0 0 1 1 *")
public void myFunc() {
do something
}
好吧,如果您真的想測試執行情況,您將不得不在新年前夕監視應用程序;<)
如果您想測試調度是否已正確設置並且您的任務是否已調度,那么您可以自動裝配 ScheduledStaskHolder 並查詢您的任務。 假設這個實現:
package nl.benooms.scheduledannotationplayground;
@Service
public class FixedDateSchedule {
@Scheduled(cron = "0 0 0 1 1 *")
public void OnceAYearCron() {
System.out.println("yearly");
}
}
那么測試可能是:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
class FixedDateScheduleTest {
@Autowired
private ScheduledTaskHolder scheduledTaskHolder;
@Test
public void testYearlyCronTaskScheduled() {
Set<ScheduledTask> scheduledTasks = scheduledTaskHolder.getScheduledTasks();
scheduledTasks.forEach(scheduledTask -> scheduledTask.getTask().getRunnable().getClass().getDeclaredMethods());
long count = scheduledTasks.stream()
.filter(scheduledTask -> scheduledTask.getTask() instanceof CronTask)
.map(scheduledTask -> (CronTask) scheduledTask.getTask())
.filter(cronTask -> cronTask.getExpression().equals("0 0 0 1 1 *") && cronTask.toString().equals("nl.benooms.scheduledannotationplayground.FixedDateSchedule.OnceAYearCron"))
.count();
assertThat(count).isEqualTo(1L);
}
}
如果出現以下情況,測試將失敗:
我試圖完全按照 Ben Ooms 的建議去做,但它對我不起作用。
我沒有使用注釋設置我的計划任務,我已經實施了一種解決方法來使用自動裝配的“TaskScheduler”來安排它們,盡管它正在工作,但我無法在 ScheduledTaskHolder 中找到我的計划任務。
原來我必須聲明一個 Bean 像:
@Configuration
class SchedulerConfiguration {
@Bean
fun threadPoolTaskScheduler(): TaskScheduler {
val scheduler = ThreadPoolTaskScheduler()
scheduler.poolSize = 20
return scheduler
}
}
並使用接口安排我的任務: SchedulingConfigurer
:
class MySchedulers(
private val myService: MyService,
@Qualifier("threadPoolTaskScheduler") private val threadPoolTaskScheduler: TaskScheduler
) : SchedulingConfigurer {
private val logger = Logger(this::class.java)
private val cronExpression = "0 0 10 * * *"
override fun configureTasks(taskRegistrar: ScheduledTaskRegistrar) {
taskRegistrar.setTaskScheduler(threadPoolTaskScheduler)
logger.info("Setting scheduler cron=$cronExpression")
taskRegistrar.addCronTask(CronTask({ runMyTask() }, CronTrigger(cronExpression)))
}
}
private fun runMyTask() {
myService.update()
}
}
然后我可以按照 Ben Ooms 的建議使用 ScheduledTaskHolder 成功找到我的計划任務。
想想你真正想要測試什么。
我認為您不應該測試@Scheduled
是否在做它應該做的事情。 這個測試應該是 spring 框架的一部分,你不應該關心測試框架。
如果您正確應用@Scheduled
可能是一個有意義的測試,並且 Ben Ooms 的答案提供了解決方案。 但是,您很可能正確地應用了它,一旦您在開發模式下運行您的應用程序,很可能會看到它是否有效。
更重要的測試,如果你的cron
規范正確建模領域的需求。
a) 在我看來,它更重要,因為它很容易搞砸,因為它沒有對每個值都有明確的表示法,並且與 UNIX cron 作業不同。 測試可以采用指定的注釋值並檢查它是否對域需求建模,即您的0 0 1 1 *
-String 實際上意味着executed at 1 January 00:00 of each year
。
b) 另一種測試方法是在測試期間操縱Clock
以將其顯式設置為預期時間並查看調度程序是否觸發該方法。 然而,這可能無法捕獲所有情況——尤其是誤報(即調度程序可能會在預期的時刻觸發,但也會在其他不應該觸發的時刻觸發)。
更重要的是:測試調度的方法實際上做了它應該做的事情。 這可以是一個簡單的單元測試,但可能涉及集成測試,具體取決於域需求。 單元測試完全獨立於調度機制,因此可以像任何其他單元測試一樣實現(例如使用模擬運行器)。
我認為 3) 可能重要或不那么重要,具體取決於用例,而 4)始終非常重要。 因此,兩者都應該是測試策略的一部分。 另一方面,1) 不應該被測試,2) 很好,但可能是過度設計測試。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.