Тестирование триггера Quartz CronTrigger
Предполагая, что у меня есть CronTriggerBean
, аналогичный
<bean id="midMonthCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="reminderJobDetail" />
<property name="cronExpression" value="0 0 6 15W * ?" />
</bean>
Каков наилучший способ проверить, что этот bean будет фактически запускаться в указанную дату, то есть в будний день, ближайший к 15-му числу каждого месяца в 6 часов утра?
Обновление. Предполагается, что это unit test, поэтому я не буду запускать виртуальную машину или менять системное время.
Ответы
Ответ 1
Хорошо, во-первых, нет смысла тестировать CronTriggerBean
. Он является частью структуры spring и уже был протестирован.
Лучшим тестом может быть проверка того, что ваше выражение cron - это то, что вы ожидаете. Один из вариантов заключается в использовании класса Quartz CronExpression
. Учитывая объект CronExpression
, вы можете вызвать getNextValidTimeAfter(Date)
, который возвращается в следующий раз после указанной даты, когда выражение будет срабатывать.
Ответ 2
Я использовал CronMaker только для того, чтобы убедиться, что моя экспрессия cron хорошо сформирована, проверьте это:
http://www.cronmaker.com/
Ответ 3
- Вы всегда можете подождать до 15 июля.
- Быть более серьезным... Если это действительно ключевая часть приложения, и мне нужно его полностью протестировать. Я бы рекомендовал использовать некоторые настройки виртуализации и установить приложение на какой-либо гостевой машине. Затем вы можете играть с системными часами и тестировать разные даты/время, не тратя на него целый месяц. Кроме того, ничего, что должно было бы остановить вас от автоматизации таких тестов.
Ответ 4
Для тех, кто не использует планировщик Quartz, но вместо этого используйте TaskSchedular
напрямую:
CronSequenceGenerator generator = new CronSequenceGenerator("0 0 8 */1 * *");
Date next = generator.next(prev);
Ответ 5
Вы также можете получить триггер bean от spring и вызвать метод getFireTimeAfter
для завершения.
Ответ 6
Я нашел здесь прохладную документацию о тестировании CronExpression
:
http://www.nurkiewicz.com/2012/10/testing-quartz-cron-expressions.html
Реализация С# будет примерно такой:
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;
}
Это классная демонстрация. Но в конце я заканчиваю использование Simple Schedule.
var trigger = TriggerBuilder.Create()
.WithIdentity("trigger3", "group1")
.WithSimpleSchedule(
x =>
{
x.WithIntervalInMinutes(15);
x.RepeatForever();
}
)
.ForJob("myJob", "group1")
.Build();
Потому что это выполняется немедленно, а затем каждые x времени.