Disable @Scheduled timers for test in Spring

Problem

As soon we have timers in our project they may cause issues in our integration tests, as they start running in the most undesirable situation. E.g. during the trigger a specific function which would usually be triggered by the timer.

Solution 1

If we want to disable the timers even the construction of the beans we have to tell spring not event to lead the beans. To achieve that we require first some configuration. As we might have more than one timer it is easier to work with an own meta annotaton

Own Meta annotation

@ConditionalOnProperty(name = "my-project.timers-enabled", 
                       havingValue = "true", 
                       matchIfMissing = true)
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
public @interface TimersEnabled {

}

Use the annotation

@TimersEnabled
@Component
@RequiredArgsConstructor
public class MyTimer {
    
    private final MyService service;

    @Scheduled(fixedDelay = 30, timeUnit = TimeUnit.SECONDS)
    void scheduledMethod() {
        service.doStuff();
    }
}

Disable the timers

e.g. in the application.yml of your test resources:

my-project:
  timers-enabled: false

The timers will be disabled for any value other then true.

Solution 2

In the easiest scenario if it is a in memory Spring test we can just mock the ScheduledExecutorService and so stop any @Scheduled job executions.

    @MockBean
    private ScheduledExecutorService schedulerService;

Paul Sterl has written 58 articles

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>