简体   繁体   English

测试Quartz CronTrigger触发器

[英]Testing Quartz CronTrigger trigger

Assuming that I have a CronTriggerBean similar to 假设我有一个类似的CronTriggerBean

<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? 测试这个bean实际上会在指定日期触发的最佳方法是什么, 在每个月的15号最接近的工作日上午6点?


Update : This is supposed to be an unit test, so I'm not going to fire up a VM or change the system time. 更新 :这应该是一个单元测试,所以我不会启动VM或更改系统时间。

Well firstly, there's no point in testing CronTriggerBean itself. 首先,测试CronTriggerBean本身没有意义。 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. 更好的测试可能是测试您的cron表达式是否符合预期。 One option here is to use Quartz's CronExpression class. 这里的一个选择是使用Quartz的CronExpression类。 Given a CronExpression object, you can call getNextValidTimeAfter(Date) , which returns the next time after the given Date when the expression will fire. 给定一个CronExpression对象,您可以调用getNextValidTimeAfter(Date) ,它将在表达式触发的给定Date之后返回下一次。

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

  1. You can always wait until the 15h of July. 您可以一直等到7月15日。
  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: 对于那些不使用Quartz调度程序的人,而是直接使用TaskSchedular

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 我在这里找到了关于测试CronExpression的很酷的文档: httpCronExpression

The C# implementation will be something like this: 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;
}

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. 因为这是立即执行然后每x次执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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