Spring Boot Test Slices

Spring Boot test slices load a focused subset of the application context so tests can exercise one architectural layer without starting the entire application. They are especially useful for faster, targeted integration-style tests such as controller or JPA repository testing.

A test slice is a specialized Spring Boot test configuration that limits auto-configuration and component scanning to the part of the application relevant to a particular test. This reduces startup work and makes failures easier to localize than a full `@SpringBootTest` test.

`@WebMvcTest` is designed for the Spring MVC layer. It typically configures MVC infrastructure, controllers, converters, validation, and related web components, while application dependencies such as services are normally supplied as mocks or explicitly imported. It is therefore useful for testing controller behavior without loading the persistence layer.

`@DataJpaTest` targets the JPA persistence layer. It configures repositories, JPA entities, and persistence-related infrastructure while excluding unrelated application components. Tests using this slice are transactional by default, and the transaction is normally rolled back after each test.

Slices are not limited to these two annotations; Spring Boot provides several specialized test annotations for areas such as JDBC, MongoDB, JSON serialization, and messaging. If a test genuinely needs several layers working together, `@SpringBootTest` may be more appropriate, because forcing a slice to include many additional components can remove much of its benefit.

When a slice needs a small amount of application-specific configuration, `@Import` or test-specific configuration can add it deliberately. The important interview distinction is that a slice is not simply a smaller `@SpringBootTest`: it uses a different set of auto-configurations and scanning rules.

Key points

Interview questions

What problem do Spring Boot test slices solve?

Test slices reduce the amount of the Spring application context that must be started for a focused test. For example, a controller test does not normally need database configuration, while a repository test does not need the web stack. This generally makes tests faster and keeps their scope clear. They are still Spring integration-style tests rather than plain unit tests.

What is the difference between `@WebMvcTest` and `@DataJpaTest`?

`@WebMvcTest` focuses on the Spring MVC layer, including controller-related web infrastructure. `@DataJpaTest` focuses on JPA entities, repositories, and persistence infrastructure. A controller test commonly mocks service dependencies, while a JPA slice test uses the actual repository and persistence setup. The two annotations therefore target different boundaries of the application.

Why might a bean that works in production be missing from a test slice?

A slice intentionally does not load the same complete component graph as the production application. Its auto-configuration and component scanning are restricted to the layer being tested. Consequently, a service, repository, or other bean outside the slice may not exist in the test context. You can usually provide a narrowly required dependency with a mock, `@Import`, or test configuration, depending on what the test needs.

What is special about transactions in `@DataJpaTest`?

`@DataJpaTest` tests are transactional by default. This allows repository operations to execute within a transaction during the test. The test transaction is normally rolled back afterward, which helps keep database state isolated between tests. If a test needs different transaction behavior, Spring's transaction-testing facilities can be used explicitly.

When would you deliberately use `@SpringBootTest` instead of a test slice?

I would use `@SpringBootTest` when the behavior under test depends on collaboration across multiple application layers or on broad application configuration. For example, an end-to-end application-flow test may need controllers, services, repositories, security, and other infrastructure together. A slice is preferable when the behavior can be isolated to one layer. The choice should follow the behavior being verified rather than simply optimizing for the shortest test startup time.