Open In App

Disable @EnableScheduling on Spring Tests

Last Updated : 24 Sep, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

In Spring applications, the @EnableScheduling annotation is commonly used to enable the execution of scheduled tasks. However, during testing, it may be necessary to disable this feature to avoid unwanted side effects or to control the test execution environment. This article will guide you through the process of disabling @EnableScheduling in Spring tests.

How to Disable @EnableScheduling in Spring Tests

In Spring applications, the @EnableScheduling annotation enables scheduling capabilities, allowing methods annotated with @Scheduled to be executed automatically at predefined intervals. This feature is useful for tasks such as batch processing, sending notifications, or executing recurring jobs in production environments.

However, during unit or integration testing, the automatic execution of scheduled tasks can interfere with the test environment. Scheduled tasks might modify the application state unexpectedly or trigger background processes, leading to unpredictable test results. Therefore, disabling scheduling during tests is crucial for ensuring a controlled and isolated testing environment.

Why Disable Scheduling in Tests?

  • Controlled Testing Environment: Disabling scheduling ensures that tests focus on specific units of functionality without interference from background tasks.
  • Improved Test Performance: Preventing resource-heavy scheduled tasks can enhance test execution speed.
  • Avoid Side Effects: Scheduled tasks might cause unintended side effects (e.g., database updates, file I/O), leading to inconsistent or unreliable test results.

Implementation of Disabling @EnableScheduling in Spring Tests in a Spring Boot Project

This example project demonstrates how to disable @EnableScheduling in the Spring tests of a Spring Boot application.

Step 1: Create a New Spring Boot Project

Create a new Spring Boot project using IntelliJ IDEA. Choose the following options:

  • Name: spring-disable-scheduling
  • Language: Java
  • Type: Maven
  • Packaging: Jar

Click on the Next button.

Project Metadata

Step 2: Add the Dependencies

Add the following dependencies to the Spring Boot project:

  • Spring Web
  • Lombok
  • Spring DevTools

Click on the Create button.

Add Dependencies

Project Structure

Once the project is created, the file structure will look like this:

Project Folder Structure

Step 3: Configure Application Properties

In the src/main/resources/application.properties file, add the following line to configure the application name:

spring.application.name=spring-disable-scheduling

Step 4: Create the SchedulingConfig Class

This configuration class enables scheduling in the application.

Java
package com.gfg.springdisablescheduling;

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;

// This class enables scheduling for the application.
@Configuration
@EnableScheduling
public class SchedulingConfig {
    // No additional configuration is needed here.
}

Step 5: Create the ScheduledTask Class

This is a simple scheduled task that will run every 5 seconds.

Java
package com.gfg.springdisablescheduling;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

// This class contains the scheduled task to be executed at fixed intervals.
@Component
public class ScheduledTask {

    // This method runs every 5 seconds.
    @Scheduled(fixedRate = 5000)
    public void runTask() {
        System.out.println("Scheduled task running every 5 seconds");
    }
}

Step 6: Main class

No changes are required in the main class.

Java
package com.gfg.springdisablescheduling;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

// Main application class to run the Spring Boot application.
@SpringBootApplication
public class SpringDisableSchedulingApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringDisableSchedulingApplication.class, args);
    }
}

Step 7: Disabling Scheduling in Tests

In the testing portion, to disable scheduling, we can either mock the scheduled tasks or exclude the scheduling configuration in the test context.

In this test, we will create a custom test configuration that disables the scheduler and ensures that no tasks are run during the test.

Java
package com.gfg.springdisablescheduling;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;

import static org.mockito.Mockito.*;

// Spring Boot test to verify the disabling of scheduled tasks.
@SpringBootTest
@ContextConfiguration(classes = DisableSchedulingTest.TestConfig.class) // Use test-specific config
public class DisableSchedulingTest {

    @MockBean
    private ScheduledTask scheduledTask; // Mock the scheduled task bean

    // Configuration class for testing to disable scheduling.
    @Configuration
    static class TestConfig {

        // Override TaskScheduler with a no-op scheduler to prevent tasks from running
        @Bean
        public ConcurrentTaskScheduler taskScheduler() {
            return new ConcurrentTaskScheduler(); // No-op task scheduler
        }
    }

    @Test
    public void testWithoutScheduledTasks() {
        // Test logic here
        // Verifying that the scheduled task is never called during the test
        verify(scheduledTask, never()).runTask();
    }
}

In this test:

  • We mock the scheduledTask bean to prevent its actual method from running.
  • We override the TaskSchedular bean using the test configuration and ensuring that no tasks are scheduled during the test execution.

pom.xml File:

XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.gfg</groupId>
    <artifactId>spring-disable-scheduling</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-disable-scheduling</name>
    <description>spring-disable-scheduling</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

Step 8: Running the Application

After the project is completed, it will run at port number 8080.

Application Runs

Step 9: Test the Application

When you run the DisableSchedulingTest, the test should pass without executing the scheduled task. The Mockito verification verify(scheduledTask, never()).runTask() ensures that the runTask() method is never called, confirming that scheduling has been disabled for this test.

Run the tests using below command,

mvn test

Output:

Tests Running
Tests Running

In this example project, we demonstrated how to disable @EnableScheduling in Spring tests using a custom test configuration and mock beans. By overriding the TaskScheduler and using @MockBean, we can prevent scheduled tasks from executing during tests, allowing for isolated and reliable test execution. This approach ensures that tests run without interference from background tasks, leading to better test performance and predictability.


Next Article

Similar Reads