测试 Quartz CronTrigger 触发器

发布于 2024-07-26 12:54:15 字数 491 浏览 6 评论 0原文

假设我有一个 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 实际上在其指定日期触发,在最接近每个日期 15 号的工作日一个月早上 6 点?


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

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, i.e. 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

愁杀 2024-08-02 12:54:15

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

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

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.

归属感 2024-08-02 12:54:15

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

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

苏佲洛 2024-08-02 12:54:15
  1. 您随时可以等到 7 月 15 日。
  2. 更严肃地说...如果它确实是应用程序的关键部分,并且我需要对其进行全面测试。 我建议使用一些虚拟化设置,并将应用程序安装在某些来宾计算机中。 然后您可以使用系统时钟并测试不同的日期/时间,而无需花费整整一个月的时间。 此外,没有什么可以阻止您自动化此类测试。
  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.
无人接听 2024-08-02 12:54:15

对于那些不使用 Quartz 调度程序,而是直接使用 TaskSchedular 的人:

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

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);
素染倾城色 2024-08-02 12:54:15

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

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

街角卖回忆 2024-08-02 12:54:15

我在这里找到了一个关于测试 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 次执行一次。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文