Вопрос

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

<Ол>
  • Вы можете всегда ждать до 15ч июля.
  • Будучи более серьезно ... Если это действительно ключевой частью приложения, и я вам нужно, чтобы он полностью протестирован. Я бы рекомендовал использовать некоторую виртуализации настройки и иметь приложение, установленное в какой-то гостевой машине. Тогда вы могли бы играть с системными часами и протестировать различные даты / времени, не тратя целый месяц на него. Кроме того, нет ничего, что должно остановить вас от <сильного> Automating таких тестов.
  • Для тех, кто не использует планировщик 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 раз.

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top