23 June 2013

Testing cron expression

Many people, using spring scheduling, write
@Scheduled("* * 3 * * ?")
public void myCronJob() {...
and then they wait a few days to check logs if the job is triggered correctly. And what about:
0 0/5 14,18,3-39,52 ? JAN,MAR,SEP MON-FRI 2002-2010
Fortunately, testing a cron expression is simple. But first we need a constant:
public static final String EVERYDAY_3_AM = "* * 3 * * ?"
And now, with spring's scheduling, we can use org.springframework.scheduling.support.CronSequenceGenerator
import static org.fest.assertions.api.Assertions.assertThat;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.springframework.scheduling.support.CronSequenceGenerator;

import com.googlecode.zohhak.api.Coercion;
import com.googlecode.zohhak.api.TestWith;
import com.googlecode.zohhak.api.runners.ZohhakRunner;

@RunWith(ZohhakRunner.class)
public class CronTest {

  static CronSequenceGenerator everyday_3am;

  @TestWith({
    "2013-06-10 22:20,    2013-06-11 03:00",
    "2013-06-13 01:12,    2013-06-13 03:00"
  })
  public void should_trigger_at_the_nearest_3_AM(Date now, Date nearest_3am) {

    // when
    Date nextExecution = everyday_3am.next(now);
  
    //then
    assertThat(nextExecution).isEqualTo(nearest_3am);
  }

  @BeforeClass
  static public void parseExpression() {
    everyday_3am = new CronSequenceGenerator(Constants.EVERYDAY_3_AM);
  }

  @Coercion
  public Date coerce(String date) throws ParseException {
    return new SimpleDateFormat("yyyy-MM-dd hh:mm").parse(date);
  }
}
We use static variable just to avoid multiple parsing of the same expression, as for complex scenarios there might be many parameters.
The same can be achieved with quartz library. To do this just replace CronSequenceGenerator with org.quartz.CronExpression
Date nextExecution = everyday_3am.getNextValidTimeAfter(now);
everyday_3am = new CronExpression(Constants.EVERYDAY_3_AM);

0 komentarze :

Post a comment