Тестирование Кварцевого триггера CronTrigger - PullRequest
13 голосов
/ 30 июня 2009

Предполагая, что у меня есть 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 часов утра?


Обновление : Это должен быть модульный тест, поэтому я не собираюсь запускать ВМ или изменять системное время.

Ответы [ 6 ]

17 голосов
/ 30 июня 2009

Ну, во-первых, нет смысла тестировать CronTriggerBean. Он является частью каркаса пружины и уже был протестирован.

Лучшим тестом может быть проверка того, что ваше выражение cron соответствует вашим ожиданиям. Одним из вариантов здесь является использование класса CronExpression Quartz. Для объекта CronExpression вы можете вызвать getNextValidTimeAfter(Date), который вернется в следующий раз после указанной даты, когда выражение сработает.

7 голосов
/ 23 марта 2012

Я использовал CronMaker только для того, чтобы убедиться, что мое выражение cron правильно сформировано, проверьте его: http://www.cronmaker.com/

3 голосов
/ 30 июня 2009
  1. Вы всегда можете подождать до 15 июля.
  2. Быть более серьезным ... Если это действительно ключевая часть приложения, и мне нужно, чтобы оно было полностью протестировано. Я бы порекомендовал использовать некоторые настройки virtualization и установить приложение на гостевой машине. Тогда вы можете поиграть с системными часами и протестировать разные даты / время, не тратя на это целый месяц. Более того, ничто не должно помешать вам автоматизировать таких тестов.
2 голосов
/ 13 мая 2013

Для тех, кто не использует планировщик Quartz, но вместо этого использует TaskSchedular напрямую:

CronSequenceGenerator generator = new CronSequenceGenerator("0 0 8 */1 * *");
Date next = generator.next(prev);
1 голос
/ 17 января 2011

Вы также можете получить триггерный бин из пружины и вызвать метод getFireTimeAfter для завершения.

0 голосов
/ 11 мая 2016

Я нашел здесь классную документацию по тестированию 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...