Java 石英晶体触发器的测试

Java 石英晶体触发器的测试,java,unit-testing,spring,quartz-scheduler,Java,Unit Testing,Spring,Quartz Scheduler,假设我有一个CronTriggerBean类似于 <bean id="midMonthCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail" ref="reminderJobDetail" /> <property name="cronExpression" value="0 0 6 15W * ?"

假设我有一个
CronTriggerBean
类似于

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

测试此bean在其指定日期(即最接近每月15日的工作日上午6点)实际触发的最佳方法是什么


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

  • 你可以一直等到7月15日
  • 更严重的是。。。如果它真的是应用程序的一个关键部分,我认为你需要对它进行全面测试。我建议使用一些虚拟化设置,并将应用程序安装在一些来宾计算机中。然后,您可以玩系统时钟,测试不同的日期/时间,而无需花费整整一个月的时间。此外,没有什么可以阻止您自动化此类测试

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


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

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

    我使用CronMaker只是为了确保我的cron表达式格式正确,请检查它:

    对于不使用Quartz调度程序,而是直接使用任务调度程序的用户:

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

    我在这里找到了一个关于测试
    CronExpression
    的很酷的文档:

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

    因为这会立即执行,然后每x次执行一次。

    谢谢您的回答。这应该是一个单元测试,所以我不会启动VM或更改系统时间。只是澄清一下-我不是建议您将代码更改为使用CronExpression,而是建议您的单元测试应该使用它。有趣的是,我将看一看。
    var trigger = TriggerBuilder.Create()
        .WithIdentity("trigger3", "group1")
        .WithSimpleSchedule(
            x =>
            {
                x.WithIntervalInMinutes(15);
                x.RepeatForever();
            }
        )
        .ForJob("myJob", "group1")
        .Build();