Chuck1sn
Chuck1sn

Reputation: 51

Quartz dynamic trigger not fire when using @SpringJUnitConfig, but it works fine with @SpringBootTest. Why is that?

Freamwork: Spring-Boot 3.3.5 Spring Boot Stater Quartz with quartz 2.3.2 Testcontainers 1.20.1 Jooq 3.19.13


@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Testcontainers
@JooqTest
public class AbstractQuartzTest {
  public static PostgreSQLContainer<?> postgres =
      new PostgreSQLContainer<>("postgres:16.4-alpine").withDatabaseName("mjga");

  @DynamicPropertySource
  static void postgresProperties(DynamicPropertyRegistry registry) {
    registry.add("spring.datasource.url", postgres::getJdbcUrl);
    registry.add("spring.datasource.username", postgres::getUsername);
    registry.add("spring.datasource.password", postgres::getPassword);
    registry.add("spring.flyway.locations", () -> "classpath:db/migration/test");
  }

  static {
    postgres.start();
  }
}

  @Bean("emailJobSchedulerFactory")
 public SchedulerFactoryBean emailJobSchedulerFactory(DataSource dataSource) {
    SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean();
    schedulerFactory.setSchedulerName("email-scheduler");
    schedulerFactory.setDataSource(dataSource);
    Properties props = getCommonProps();
    props.setProperty("org.quartz.threadPool.threadCount", "10");
    schedulerFactory.setQuartzProperties(props);
    return schedulerFactory;
  }

// When using @SpringJUnitConfig it doesn't work. but @SpringBootTest works fine! 
@SpringJUnitConfig(classes = QuartzConfig.class)
public class SendEmailJobTest extends AbstractQuartzTest {
  private Boolean executed;

  @Autowired
  @Qualifier("emailJobSchedulerFactory") private SchedulerFactoryBean emailJobSchedulerFactory;

  @Test
  public void emailJobScheduler_givenDynamicJobAndTrigger_shouldRunJobAtDesiredTime()
      throws Exception {
    Scheduler emailJobScheduler = emailJobSchedulerFactory.getScheduler();
    assertTrue(emailJobScheduler.isStarted());
    JobDataMap jobDataMap = new JobDataMap();
    jobDataMap.put("userEmail", "[email protected]");

    JobDetail jobDetail =
        newJob(EmailJob.class)
            .withIdentity("email-job", "customer-service")
            .usingJobData(jobDataMap)
            .build();

    Trigger trigger =
        newTrigger()
            .withIdentity("email-trigger", "customer-service")
            .startAt(futureDate(1, DateBuilder.IntervalUnit.SECOND))
            .build();

    emailJobScheduler
        .getListenerManager()
        .addJobListener(
            new JobListener() {
              @Override
              public String getName() {
                return "TestJobListener";
              }

              @Override
              public void jobToBeExecuted(JobExecutionContext context) {}

              @Override
              public void jobExecutionVetoed(JobExecutionContext context) {}

              @Override
              public void jobWasExecuted(
                  JobExecutionContext context, JobExecutionException jobException) {
                executed = Boolean.TRUE;
              }
            });
    emailJobScheduler.scheduleJob(jobDetail, trigger);
    assertTrue(emailJobScheduler.isStarted());
    await()
        .atMost(3, java.util.concurrent.TimeUnit.SECONDS)
        .untilAsserted(() -> assertThat(executed).isTrue());
  }
}

Error

Because jobWasExecuted never executed so executed flag is null. But if change @SpringJUnitConfig to @SpringBootTest it works fine!

Expecting actual not to be null
java.lang.AssertionError: 
Expecting actual not to be null
    at com.yy.xx.integration.quartz.SendEmailJobTest.lambda$emailJobScheduler_givenDynamicJobAndTrigger_shouldRunJobAtDesiredTime$0(SendEmailJobTest.java:71)
    at org.awaitility.core.AssertionCondition.lambda$new$0(AssertionCondition.java:53)
    at org.awaitility.core.ConditionAwaiter$ConditionPoller.call(ConditionAwaiter.java:248)
    at org.awaitility.core.ConditionAwaiter$ConditionPoller.call(ConditionAwaiter.java:235)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
    at java.base/java.lang.Thread.run(Thread.java:1583)

I don't want to use @SpringBootTest, which takes too much time to load the following environment, I want to use @SpringJUnitConfig(classes = QuartzConfig.class) to write unit tests.

What should I do?

Upvotes: 0

Views: 24

Answers (0)

Related Questions