Course topics

By WebNest Studio Engineering Team

Spring Boot Tutorial

Testing Spring Boot Applications

Spring Boot applications benefit from testing at different levels of the stack — a full integration test that boots the entire application context is thorough but slow, while a narrowly focused slice test loads only what's needed for one layer and runs much faster. Spring Boot Test provides annotations for exactly this range of granularity, built on JUnit Jupiter, Mockito, and AssertJ (bundled in spring-boot-starter-test; Spring Boot 4 also provides per-technology test starters such as spring-boot-starter-webmvc-test and spring-boot-starter-data-jpa-test). The lessons in this module cover each level in depth.

@SpringBootTest — Full Integration Tests

@SpringBootTest boots the entire Spring ApplicationContext, exactly like the real running application, making it suitable for true end-to-end integration tests. It's the slowest test type since it wires up every bean, so it should be used deliberately rather than for every test class — typically for a handful of tests that verify the whole system works together, often combined with webEnvironment = RANDOM_PORT and a real HTTP client for true black-box testing.

@WebMvcTest — Controller Slice Tests

@WebMvcTest(ControllerClass.class) loads only the Spring MVC infrastructure and the specified controller, without starting the full context (no real database, no service beans unless mocked). Combined with MockMvc, it lets you send simulated HTTP requests and assert on status codes, headers, and JSON response bodies quickly, while service dependencies are supplied as @MockitoBean (Spring Boot 4 removed the older @MockBean).

@DataJpaTest — Repository Slice Tests

@DataJpaTest configures only the JPA-related components — an in-memory embedded database (by default), your repository interfaces, and Hibernate — without loading controllers or unrelated services. Each test method runs inside a transaction that's rolled back afterward, keeping tests isolated from each other without manual cleanup.

Example

A controller slice test with MockMvc and a repository slice test with @DataJpaTest

Java
@WebMvcTest(ProductController.class)
class ProductControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockitoBean
    private ProductService productService;

    @Test
    void getById_returnsProduct_whenFound() throws Exception {
        when(productService.findById(5L))
                .thenReturn(Optional.of(new Product(5L, "Wireless Mouse", new BigDecimal("19.99"))));

        mockMvc.perform(get("/api/products/5"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.name").value("Wireless Mouse"));
    }
}

@DataJpaTest
class ProductRepositoryTest {

    @Autowired
    private ProductRepository repository;

    @Test
    void findByCategory_returnsMatchingProducts() {
        repository.save(new Product(null, "Keyboard", "Electronics", new BigDecimal("45.00")));
        repository.save(new Product(null, "Desk Lamp", "Home", new BigDecimal("22.00")));

        List<Product> results = repository.findByCategory("Electronics");

        assertThat(results).hasSize(1);
        assertThat(results.get(0).getName()).isEqualTo("Keyboard");
    }
}
Output
ProductControllerTest > getById_returnsProduct_whenFound() PASSED
ProductRepositoryTest > findByCategory_returnsMatchingProducts() PASSED

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0

Common Mistakes

  • Using @SpringBootTest for every test class, causing the full application context to boot repeatedly and slowing the test suite dramatically as the project grows.
  • Forgetting @MockitoBean for a controller's dependencies inside @WebMvcTest, causing context startup failures because the real service bean (and its own dependencies, like a database) is not available in that slice.
  • Testing the repository layer against production-like assumptions without realizing @DataJpaTest uses an embedded in-memory database by default, whose SQL dialect quirks can differ subtly from the real production database.
  • Not resetting shared mutable state between tests, causing flaky, order-dependent test failures.

Exercise

A teammate is about to make this mistake: Using @SpringBootTest for every test class, causing the full application context to boot repeatedly and slowing the test suite dramatically as the project grows. Use @SpringBootTest — Full Integration Tests to review the decision. Write a corrected implementation or design sketch that follows @SpringBootTest boots the full application context — thorough but slow, best used for true integration tests., then name one edge case you would check.

Show hints
  • Start with @SpringBootTest — Full Integration Tests and compare your approach with A controller slice test with MockMvc and a repository slice test with @DataJpaTest. Identify the decision or behavior the lesson recommends.
  • Walk through your scenario step by step. Confirm that it follows @SpringBootTest boots the full application context — thorough but slow, best used for true integration tests. and that it would catch the failure described by Using @SpringBootTest for every test class, causing the full application context to boot repeatedly and slowing the test suite dramatically as the project grows..

Quick quiz

1. Which choice best describes the recommended approach in Testing Spring Boot Applications?

  • A. Using @SpringBootTest for every test class, causing the full application context to boot repeatedly and slowing the test suite dramatically as the project grows.
  • B. Forgetting @MockitoBean for a controller's dependencies inside @WebMvcTest, causing context startup failures because the real service bean (and its own dependencies, like a database) is not available in that slice.
  • C. @SpringBootTest boots the full application context — thorough but slow, best used for true integration tests.
Show answer

C. This is the recommended approach: @SpringBootTest boots the full application context — thorough but slow, best used for true integration tests. Avoid: Using @SpringBootTest for every test class, causing the full application context to boot repeatedly and slowing the test suite dramatically as the project grows.

Interview questions

Why does this principle matter in Testing Spring Boot Applications: @SpringBootTest boots the full application context — thorough but slow, best used for true integration tests.

Show answer

@SpringBootTest boots the full application context — thorough but slow, best used for true integration tests. Apply this in @SpringBootTest — Full Integration Tests; the example A controller slice test with MockMvc and a repository slice test with @DataJpaTest shows one way to do it. Avoid Using @SpringBootTest for every test class, causing the full application context to boot repeatedly and slowing the test suite dramatically as the project grows. and explain how your implementation or design prevents that failure.

Key Points to Remember

  • @SpringBootTest boots the full application context — thorough but slow, best used for true integration tests.
  • @WebMvcTest loads only MVC infrastructure and one controller, paired with MockMvc (or MockMvcTester) and @MockitoBean for fast controller tests.
  • @DataJpaTest loads only JPA components with an embedded database and per-test transaction rollback, ideal for repository tests.
  • spring-boot-starter-test bundles JUnit Jupiter, Mockito, and AssertJ; add the per-technology test starters for slices in Spring Boot 4.

Practice in the playground

Write and run your own code for this topic, or start from the exercise or an example. Runs plain Java 17. Frameworks such as Spring, and databases, are not available here. Your code for each topic is kept in this browser.

Run the examples

Change an input, predict the result, then compare it with the output. Explain why the result changes.

These examples need a JDK project with their libraries on your computer, so they can be copied but not run here. Codelab runs Python, FastAPI backends with SQLite, plain Java 17 and HTML/CSS/JavaScript.

WebNest Studio

Written by

WebNest Studio Engineering Team

Practical lessons from developers working with Java, Python, React, databases and production systems.

Led by Vansh Duggal, Founder, WebNest Studio · Full-stack & software engineering