简体   繁体   中英

Testing Quartz CronTrigger trigger

Assuming that I have a CronTriggerBean similar to

<bean id="midMonthCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
    <property name="jobDetail" ref="reminderJobDetail" />
    <property name="cronExpression" value="0 0 6 15W * ?" />
</bean>

What is the best way to test that this bean will actually trigger at its specified date, ie on the weekday closest to the 15th of each month at 6 AM?


Update : This is supposed to be an unit test, so I'm not going to fire up a VM or change the system time.

Well firstly, there's no point in testing CronTriggerBean itself. It's part of the spring framework, and has already been tested.

A better test might be to test that your cron expression is what you expect. One option here is to use Quartz's CronExpression class. Given a CronExpression object, you can call getNextValidTimeAfter(Date) , which returns the next time after the given Date when the expression will fire.

我只使用CronMaker来确定我的cron表达是否形成良好,请查看: http ://www.cronmaker.com/

  1. You can always wait until the 15h of July.
  2. Being more serious... If it's really a key part of the application and I you need to have it tested fully. I would recommend using some virtualization setups and have the application installed within some guest machine. Then you could play with the system clock and test different date/times without spending a whole month on it. Moreover there's nothing that should stop you from automating such tests.

For those who don't use the Quartz scheduler, but instead use the TaskSchedular directly:

CronSequenceGenerator generator = new CronSequenceGenerator("0 0 8 */1 * *");
Date next = generator.next(prev);

您还可以从spring获取触发器bean并调用getFireTimeAfter方法来完成。

I found a cool documentation here about testing the CronExpression : http://www.nurkiewicz.com/2012/10/testing-quartz-cron-expressions.html

The C# implementation will be something like this:

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;
}

This is a cool demo. But at the end, I end using Simple Schedule.

var trigger = TriggerBuilder.Create()
    .WithIdentity("trigger3", "group1")
    .WithSimpleSchedule(
        x =>
        {
            x.WithIntervalInMinutes(15);
            x.RepeatForever();
        }
    )
    .ForJob("myJob", "group1")
    .Build();

Because this is executed immediately and then every x time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM