Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

A vertical slice groups the code for one application capability—such as placing an order—across the layers needed to deliver it. Testing that capability is different from using Spring Boot’s technical test slices: @WebMvcTest narrows the test context to MVC concerns, while @DataJpaTest focuses on JPA. For a functional module tested across its layers, Spring Modulith provides @ApplicationModuleTest.

What a vertical slice means in a Spring Boot application

A vertical slice is a functional boundary, not a framework layer. A module can contain its own web endpoint, application logic, domain model, and persistence code. Other modules should use its exposed interface rather than reach into its internal implementation.

Spring Modulith describes an application module in terms of three parts: a provided interface, which can expose Spring beans and published events; internal implementation components; and required interfaces to other modules, such as their APIs, events, or configuration properties. Its default convention treats direct sub-packages of the package containing the main Spring Boot application class as modules.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

One possible package layout is:

com.example.shop
  ShopApplication.java
  orders/
    OrderController.java
    PlaceOrder.java
    OrderRepository.java
    Order.java
  inventory/
    InventoryApi.java
    InventoryService.java
    StockRepository.java

This illustrates one way to organize capabilities; it is not a structure Spring Boot requires. Spring Modulith can help verify module structure and test modules, but teams can use vertical slices without adopting it.

Vertical module tests and Boot test slices are different

The word “slice” refers to two different scopes in this context. Spring Boot’s test-slice annotations select framework concerns and load a reduced test context. A Spring Modulith application module represents a functional boundary that can include multiple technical layers.

Approach Question it answers What it loads Key caution
Plain unit test Does this rule or object behave correctly? Objects constructed directly, without Spring when possible Does not prove Spring wiring or framework integration.
@WebMvcTest Does this MVC endpoint behave correctly? MVC infrastructure and selected MVC beans, including MockMvc Ordinary components and configuration-properties beans are excluded unless added.
@DataJpaTest Do entity mappings and repositories behave correctly? JPA entities, repositories, and database test setup An embedded database may not match production database behavior.
@ApplicationModuleTest Does this functional module work across its layers? The current application module, with optional dependencies External module beans must be included or replaced as appropriate.
@SpringBootTest Does broad application wiring or an end-to-end path work? The application context, optionally with a mock or real web environment Use its broader scope when the behavior under test needs it.

The scopes and behaviors in this comparison are documented by the Spring Boot testing reference, the Spring Modulith testing reference, and the Spring Boot test-slices reference. These are qualitative scope differences, not measured speed comparisons.

Choose the test boundary that matches the behavior

Test simple business rules without starting Spring

If a rule can be tested by constructing its objects directly, use a plain unit test. This can check decisions such as whether an order is eligible for a discount without testing dependency injection or framework behavior. Spring’s test context is useful when the behavior depends on that context; it is not necessary for every business-rule check.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use @WebMvcTest for controller behavior

Use this annotation to test request mapping, validation, serialization, and MVC exception handling. It auto-configures Spring MVC and MockMvc, while limiting component scanning to MVC-related types. Ordinary @Component and @ConfigurationProperties beans are not scanned by default, so provide required collaborators as test doubles or import only the configuration the test needs. If Spring Security is part of the application, use its test support rather than assuming security behavior has been removed.

Use @DataJpaTest for mappings and repositories

Use this annotation to check JPA entity mapping and repository behavior. It scans entities and configures Spring Data JPA repositories; when an embedded database is on the classpath, Spring Boot configures one. These tests are transactional and roll back after each test by default.

An embedded database does not establish compatibility with a production database’s dialect, locking, or vendor-specific features. If one of those behaviors matters to the claim your test makes, configure the test to use the real database rather than replacing it with an embedded one.

Use @ApplicationModuleTest for a capability across layers

Spring Modulith’s module test support bootstraps the application module containing the test, letting the test exercise that module across its layers. Place the test in the module package or a sub-package and annotate it with @ApplicationModuleTest. The bootstrap mode determines which modules are available:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • STANDALONE: the current module.
  • DIRECT_DEPENDENCIES: the current module and its direct dependencies.
  • ALL_DEPENDENCIES: the current module and its dependency tree.

If the module needs a bean from another module, include the relevant dependency deliberately or replace the external bean with @MockitoBean. A test that needs many beans from other modules can be a prompt to review coupling and boundaries. Domain events may be worth considering, but they are not automatically the right replacement for every bean dependency.

For event-driven behavior, Spring Modulith’s Scenario abstraction lets a test define a stimulus—such as publishing an event or invoking an exposed component—and an expected result, such as a matching event or an observable state change in the module. Asynchronous and transactional event handling can involve concurrency and event-processing details, so account for those in the scenario you test.

Combine module scope with a technical slice when needed

If the question is specifically about the repository layer inside one functional module, Spring Modulith documents combining @ModuleSlicing with a Boot slice such as @DataJpaTest. This selects both a module boundary and a technical layer. It is distinct from @ApplicationModuleTest, which tests the module with its layers together.

Reserve @SpringBootTest for broad behavior

@SpringBootTest creates an application context through SpringApplication; by default, it does not start a server. Its webEnvironment option can select a mock environment or start a real server on a random port. Choose a real server when the behavior depends on actual HTTP-server startup or network behavior, rather than using it for every test.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

When focused tests fail to load

A bean is missing from a test slice

A missing bean in @WebMvcTest or @DataJpaTest can mean the annotation excluded it by design, not that production wiring is broken. Add a test double or import only the configuration required for the behavior under test. Boot also cautions that an explicit @ComponentScan on the main @SpringBootApplication can disable the default filters used for slicing. Consider moving custom scanning into separate configuration or restoring the relevant filters.

A module test needs another module

Decide whether the test should include that module as a dependency or replace its bean with a test double. If many external beans are needed, examine whether the module boundary exposes the right interface and whether the dependency pattern is appropriate.

A database test passes only with an embedded database

Check whether the test’s claim is limited to repository behavior that is database-independent. For dialect-specific, locking, or vendor-specific behavior, run against the database whose behavior matters; configure @DataJpaTest not to replace the configured database when needed.

Keep examples aligned with the Boot version

Spring Boot’s reference documentation lists stable versions including 4.1.1 and 3.5.16 as of October 7, 2026. Test dependency coordinates and package names can vary between Boot releases, so use the documentation and dependencies for the version declared by your project rather than mixing examples across generations. Spring Modulith’s cited reference pages do not establish a specific release here; check the release documentation for the version used by your project.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Spring’s test framework caches application contexts between tests that share configuration. A context-based test therefore does not necessarily reload the application for every test method.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.