Тестирование кварцевого триггера CronTrigger
-
21-08-2019 - |
Вопрос
Предполагая, что у меня есть CronTriggerBean
похожий на
<bean id="midMonthCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="reminderJobDetail" />
<property name="cronExpression" value="0 0 6 15W * ?" />
</bean>
Каков наилучший способ проверить, что этот компонент действительно сработает в указанную дату, т. е. в будний день, ближайший к 15-му числу каждого месяца, в 6 утра?
Обновить:Предполагается, что это модульный тест, поэтому я не собираюсь запускать виртуальную машину или изменять системное время.
Решение
Ну, во-первых, нет смысла тестировать CronTriggerBean
сам по себе.Это часть spring Framework, и она уже была протестирована.
Лучшим тестом может быть проверка того, что ваше выражение cron соответствует вашим ожиданиям.Одним из вариантов здесь является использование Quartz's CronExpression
класс.Учитывая, что CronExpression
объект, который вы можете вызвать getNextValidTimeAfter(Date)
, который возвращает в следующий раз после заданной даты, когда выражение сработает.
Другие советы
Я использовал CronMaker только для того, чтобы убедиться, что мое выражение cron правильно сформировано, проверьте это:http://www.cronmaker.com/
Для тех, кто не использует планировщик Quartz, но вместо этого использует TaskSchedular
непосредственно:
CronSequenceGenerator generator = new CronSequenceGenerator("0 0 8 */1 * *");
Date next = generator.next(prev);
Вы также можете получить компонент-триггер из spring и вызвать getFireTimeAfter
способ закончить.
Я нашел здесь классную документацию о тестировании CronExpression
:
http://www.nurkiewicz.com/2012/10/testing-quartz-cron-expressions.html
Реализация на C # будет примерно такой:
void Run()
{
//var collection = findTriggerTimesRecursive(new CronExpression("0 0 17 L-3W 6-9 ? *"), DateTime.UtcNow);
var collection = findTriggerTimesRecursive(new CronExpression("0 0/15 * 1/1 * ? *"), DateTime.UtcNow);
Console.WriteLine(DateTime.UtcNow);
foreach (var item in collection)
{
Console.WriteLine(item);
}
}
public List<DateTimeOffset> findTriggerTimesRecursive(CronExpression expr, DateTimeOffset from, int max = 10)
{
var times = new List<DateTimeOffset>();
var next = expr.GetNextValidTimeAfter(from);
while (next != null && times.Count < max)
{
times.Add(next.Value);
from = next.Value;
next = expr.GetNextValidTimeAfter(from);
}
return times;
}
Это классная демо-версия.Но, в конце концов, я заканчиваю использовать Простое расписание.
var trigger = TriggerBuilder.Create()
.WithIdentity("trigger3", "group1")
.WithSimpleSchedule(
x =>
{
x.WithIntervalInMinutes(15);
x.RepeatForever();
}
)
.ForJob("myJob", "group1")
.Build();
Потому что это выполняется немедленно, а затем каждый x раз.