Spring Boot @SpringBootTest Annotation | Test Spring Boot Applications

🚀 Introduction: What is @SpringBootTest in Spring Boot?

The @SpringBootTest annotation in Spring Boot is used for integration testing by loading the full application context. It allows you to test Spring Boot components such as services, controllers, and repositories in a real Spring environment.

Key Features of @SpringBootTest:
✔ Loads the entire application context for testing.
✔ Supports dependency injection in test classes.
✔ Works with JUnit and TestNG for unit and integration tests.
✔ Can be configured to load specific components or mock dependencies.

📌 In this guide, you’ll learn:
How @SpringBootTest works in Spring Boot testing.
How to configure @SpringBootTest for different testing scenarios.
Best practices for writing efficient tests.

1️⃣ Basic Example: Writing a Simple @SpringBootTest

📌 Example: Testing a Service Layer Using @SpringBootTest

1. Service Class (UserService.java)

@Service
public class UserService {

    public String getUserGreeting(String name) {
        return "Hello, " + name + "!";
    }
}

2. Test Class (UserServiceTest.java)

@SpringBootTest
class UserServiceTest {

    @Autowired
    private UserService userService;

    @Test
    void testGetUserGreeting() {
        String result = userService.getUserGreeting("Ramesh");
        assertEquals("Hello, Ramesh!", result);
    }
}

📌 Test Output (JUnit 5):

Test passed ✅

The @SpringBootTest annotation loads the application context and injects the UserService bean.

2️⃣ @SpringBootTest vs @WebMvcTest vs @DataJpaTest

Annotation Purpose Components Loaded
@SpringBootTest Full application context testing All Spring components (Controllers, Services, Repositories, Beans, etc.)
@WebMvcTest Controller layer testing Only controllers (@Controller or @RestController)
@DataJpaTest Repository and database layer testing Only repository (@Repository) beans with in-memory database

📌 Example: Using @WebMvcTest for Controller Testing

@WebMvcTest(UserController.class)
class UserControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void testGetUser() throws Exception {
        mockMvc.perform(get("/api/users/1"))
                .andExpect(status().isOk())
                .andExpect(content().string("User with ID: 1"));
    }
}

Use @WebMvcTest for testing only the controller layer.

3️⃣ Using @SpringBootTest with a Random Port (For API Testing)

Use @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) to start the application with a random port for real HTTP testing.

📌 Example: Testing REST API with Random Port

1. Controller (UserController.java)

@RestController
@RequestMapping("/api/users")
public class UserController {

    @GetMapping("/{id}")
    public String getUserById(@PathVariable int id) {
        return "User with ID: " + id;
    }
}

2. Test Class (UserControllerTest.java)

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class UserControllerTest {

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    void testGetUserById() {
        String response = restTemplate.getForObject("/api/users/1", String.class);
        assertEquals("User with ID: 1", response);
    }
}

📌 Test Output:

Test passed ✅

The test runs with a random port and makes actual API calls using TestRestTemplate.

4️⃣ Mocking Dependencies in @SpringBootTest with @MockitoBean

In Spring Boot unit testing, @MockBean has been widely used to mock dependencies in test cases. However, starting from Spring Boot 3.2, @MockBean is deprecated and replaced with @MockitoBean.

To avoid loading real database connections, use @MockitoBean to create mock dependencies.

📌 Example: Mocking a Repository in @SpringBootTest

1. Repository (UserRepository.java)

public interface UserRepository extends JpaRepository<User, Integer> {
    Optional<User> findByEmail(String email);
}

2. Service (UserService.java)

@Service
public class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public Optional<User> getUserByEmail(String email) {
        return userRepository.findByEmail(email);
    }
}

3. Test Class (UserServiceTest.java)

@SpringBootTest
class UserServiceTest {

    @Autowired
    private UserService userService;

    @MockitoBean
    private UserRepository userRepository;

    @Test
    void testGetUserByEmail() {
        when(userRepository.findByEmail("test@example.com"))
                .thenReturn(Optional.of(new User(1, "Test User", "test@example.com")));

        Optional<User> user = userService.getUserByEmail("test@example.com");

        assertTrue(user.isPresent());
        assertEquals("Test User", user.get().getName());
    }
}

📌 Test Output:

Test passed ✅

Using @MockitoBean, the repository is replaced with a mock object, avoiding actual database calls.

5️⃣ Testing a Spring Boot Application with CommandLineRunner

If your Spring Boot application uses a CommandLineRunner, disable it during testing to prevent unintended execution.

📌 Example: Disabling CommandLineRunner in Tests

1. Command Line Runner (AppRunner.java)

@Component
public class AppRunner implements CommandLineRunner {

    @Override
    public void run(String... args) {
        System.out.println("Application started!");
    }
}

2. Test Class with Disabled CommandLineRunner

@SpringBootTest(properties = "spring.main.allow-bean-definition-overriding=true")
class ApplicationTests {

    @Test
    void contextLoads() {
        // No execution of CommandLineRunner
    }
}

Prevents CommandLineRunner from running in tests.

🎯 Summary: Best Practices for Using @SpringBootTest

Use @SpringBootTest for full integration tests.
Use @WebMvcTest for testing only controllers.
Use @MockitoBean to mock dependencies instead of real database connections.
Use @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) for API tests.
Disable CommandLineRunner in test configurations when necessary.

🚀 Following these best practices ensures robust and maintainable tests in Spring Boot!

Comments

Spring Boot 3 Paid Course Published for Free
on my Java Guides YouTube Channel

Subscribe to my YouTube Channel (165K+ subscribers):
Java Guides Channel

Top 10 My Udemy Courses with Huge Discount:
Udemy Courses - Ramesh Fadatare