java 测试 Quartz CronTrigger 触发器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1060567/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 14:58:54  来源:igfitidea点击:

Testing Quartz CronTrigger trigger

javaunit-testingspringquartz-scheduler

提问by Robert Munteanu

Assuming that I have a CronTriggerBeansimilar 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, i.e.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.

更新:这应该是一个单元测试,所以我不会启动虚拟机或更改系统时间。

回答by skaffman

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

首先,测试CronTriggerBean本身没有意义。它是 spring 框架的一部分,并且已经过测试。

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

更好的测试可能是测试您的 cron 表达式是否符合您的预期。这里的一种选择是使用 Quartz 的CronExpression类。给定一个CronExpression对象,您可以调用getNextValidTimeAfter(Date),它会在给定日期之后的下一次表达式触发时返回。

回答by domix

I used CronMaker only to be sure if my cron expression is well formed, check it out: http://www.cronmaker.com/

我使用 CronMaker 只是为了确定我的 cron 表达式是否格式正确,请查看:http://www.cronmaker.com/

回答by Grzegorz Oledzki

  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 virtualizationsetups 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 automatingsuch tests.
  1. 您可以一直等到 7 月 15 日。
  2. 更认真...如果它真的是应用程序的关键部分,而我则需要对其进行全面测试。我建议使用一些虚拟化设置并将应用程序安装在一些来宾机器中。然后,您可以使用系统时钟并测试不同的日期/时间,而无需花费整整一个月的时间。此外,没有什么可以阻止您自动化此类测试。

回答by Varun Achar

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

对于那些不使用 Quartz 调度器,而是TaskSchedular直接使用:

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

回答by Allen

You also can get the trigger bean from spring and invoke the getFireTimeAftermethod to finish.

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

回答by Jaider

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

我在这里找到了一个关于测试的很酷的文档CronExpressionhttp: //www.nurkiewicz.com/2012/10/testing-quartz-cron-expressions.html

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.

这是一个很酷的演示。但最后,我最终使用了 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 次执行一次。