-
Notifications
You must be signed in to change notification settings - Fork 0
Triggers and Tasks in JUnit Tests
The SchedulerService
can be disabled for unit testing, which ensures that no trigger will be
executed automatically.
spring:
persistent-tasks:
scheduler-enabled: false
Now you can run any trigger manually using the TriggerService
NOTE: Using the
TriggerService
is recommended to see any errors which might arise.
@Autowired
private TriggerService triggerService;
@Test
void testRunTriggerDirectly() {
// GIVEN
// setup your test and create any triggers needed
var trigger = TaskTriggerBuilder
.<Vehicle>newTrigger("task2")
.id("my-id") // will overwrite existing triggers
.state(new Vehicle("funny"))
.build();
// WHEN create and directly run this trigger
triggerService.run(triggerService.queue(trigger));
// THEN
// any asserts you might need
}
@Test
void testRunUnknownTriggersCreated() {
// GIVEN
// setup your test call any method which might create triggers
// WHEN run any pending triggers
triggerService.run(triggerService.lockNextTrigger("test"));
// THEN
// any asserts you might need
}
Sometimes it might be useful quickly to execute all running tasks. This sample adds a method e.g. to your base test class which will trigger any task which is now due to be executed.
@Autowired
protected TriggerService triggerService;
protected int waitForDbSchedulerTasks() {
TriggerEntity t;
int count = 0;
while ((t = triggerService.lockNextTrigger("test")) != null) {
triggerService.run(t);
++count;
}
return count;
}
A common use case is run tasks which should run in the future or just to wait that all retries are exceeded.
@Autowired
protected TriggerService triggerService;
protected int waitForDbSchedulerTasks(OffsetDateTime thenToRun) {
List<TriggerEntity> triggers;
int count = 0;
while (!(triggers = triggerService.lockNextTrigger("test", 1, thenToRun)).isEmpty()) {
triggerService.run(triggers.get(0));
++count;
}
return count;
}
It is also possible to define a test scheduler and use the async way to execute any triggers (without the spring scheduler which would trigger them automatically).
NOTE: Any errors are now in the log and are handled by the framework with retries etc.
@Configuration
public static class TestConfig {
@Primary
@SuppressWarnings("resource")
SchedulerService schedulerService(TriggerService triggerService, EditSchedulerStatusComponent editSchedulerStatus,
TransactionTemplate trx) throws UnknownHostException {
final var taskExecutor = new TaskExecutorComponent(triggerService, 10);
taskExecutor.setMaxShutdownWaitTime(Duration.ofSeconds(0));
return new SchedulerService("testScheduler", triggerService, taskExecutor, editSchedulerStatus, trx);
}
}
Now the PersistentTaskService
has a method to trigger or to trigger and to wait for the result:
@Autowired
private PersistentTaskService persistentTaskService;
@Test
void testFoo() {
// GIVEN
// setup your test and create any triggers needed
// WHEN run any pending triggers
persistentTaskService.executeTriggersAndWait();
// THEN
// any asserts you might need
}
During the setup and cleanup it is possible to cancel any pending triggers:
@BeforeEach
public void beforeEach() throws Exception {
triggerService.deleteAll();
historyService.deleteAll();
schedulerService.setMaxThreads(10);
schedulerService.start();
}
@AfterEach
public void afterEach() throws Exception {
// will cancel any pending tasks
schedulerService.shutdownNow(); // use .stop() if you want to wait
}