When and how would you use the classes attribute of @SpringBootTest to override configuration detection?
answer
- classes = ... skips the package search
- Only listed beans + their imports/scans
- Plain @Configuration => no component scan, no auto-config
- Use for leaner/faster or library modules
- Boot front for @ContextConfiguration(classes)
basics
~10 sSet @SpringBootTest(classes = {MyConfig.class}) to tell the test exactly which @Configuration classes to load. This bypasses the package-tree search entirely, so the context contains only what those classes define plus what they import.
solid answer
~40 sThe `classes` attribute lets you name the configuration classes explicitly instead of relying on `@SpringBootConfiguration` discovery. Passing `@SpringBootTest(classes = TestConfig.class)` short-circuits the upward package search — the finder is never consulted. Use it when: the auto-discovered main class pulls in too much (heavy auto-configuration, external clients) and you want a leaner, faster context; when there's no `@SpringBootApplication` reachable from the test (e.g. a library module); or when two `@SpringBootConfiguration` classes would otherwise make discovery ambiguous. A key subtlety: naming a plain `@Configuration` in `classes` does **not** enable component scanning or auto-configuration by itself — you get only the beans those classes declare or import. To keep auto-config, point `classes` at a class annotated with `@SpringBootApplication`/`@EnableAutoConfiguration`, or add those annotations to your test config.
code
java · 19 lines@SpringBootTest(classes = { OrderService.class, PricingConfig.class })
class OrderServiceSliceTest {
// Context contains ONLY OrderService + what PricingConfig declares/imports.
// No component scan of com.myapp.**, no auto-configuration.
@Autowired OrderService service;
@Test void computesTotal() {
assertThat(service.total(cart)).isEqualByComparingTo("42.00");
}
}
// To keep auto-config while still overriding, name a Boot-annotated class:
@SpringBootTest(classes = TestApp.class)
class FullContextTest {
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.myapp.order")
static class TestApp {}
}go deeper
Know that classes lets you name the config explicitly.
Explain that it skips discovery and that a plain @Configuration drops scanning + auto-config.
Weigh leaner explicit config vs full context for speed and isolation; know the @ContextConfiguration relationship.
Set team conventions for when to override, avoiding context-cache fragmentation from too many bespoke configs.
### What the attribute does `@SpringBootTest(classes = ...)` explicitly lists the component/configuration classes used to build the test `ApplicationContext`. When present, Spring Boot **skips** the `@SpringBootConfiguration` package-tree discovery entirely and uses exactly what you provide (plus whatever those classes `@Import`, scan, or enable). ### When to reach for it - **Leaner context:** the real `@SpringBootApplication` triggers auto-configuration for the whole app (data sources, security, messaging clients). If your test only needs a couple of beans, listing a small `@Configuration` builds a smaller, faster context. - **No reachable main class:** in a library or a module without a `@SpringBootApplication`, discovery would fail (`Unable to find a @SpringBootConfiguration`). `classes` gives it a target. - **Disambiguation:** if two `@SpringBootConfiguration` classes are in scope, discovery is ambiguous; naming one resolves it. - **Custom test wiring:** supply a test-specific config that swaps in fakes/stubs. ### The crucial gotcha: you lose the convention magic `@SpringBootApplication` bundles three things: `@SpringBootConfiguration` (+ `@Configuration`), `@ComponentScan`, and `@EnableAutoConfiguration`. If you point `classes` at a bare `@Configuration`, you get **only** the beans it declares/imports — **no** component scanning of your packages and **no** auto-configuration. Your `@Repository`, `@Service`, `@Controller` beans elsewhere won't be picked up unless the named config scans or imports them. To retain auto-config, either name a class carrying `@SpringBootApplication`/`@EnableAutoConfiguration`, or add those annotations to the test config class. ### Related knobs - `@ContextConfiguration(classes = ...)` (Spring TestContext, the lower-level mechanism) does the same explicit-config job; `@SpringBootTest`'s `classes` is the Boot-flavored front for it. - Nested `static @Configuration` / `@TestConfiguration` classes inside the test can supplement (not replace) the primary config; `@TestConfiguration` is *additive* and only applies when included. - `properties`/`args` on `@SpringBootTest` tune the environment but don't change which config is selected. ### Interview framing The expected insight is that `classes` is an escape hatch from convention, and that misusing it (naming a plain `@Configuration` and expecting a full app) silently produces a context missing your scanned beans and auto-configuration.
- If you pass a plain @Configuration to classes, why might your @Service beans be missing from the context?Because naming a bare @Configuration bypasses discovery AND doesn't enable @ComponentScan. Only beans that config declares or explicitly imports/scans exist. Your @Service classes elsewhere are never scanned, so they're absent — you'd need the config to scan or import them, or to name a @ComponentScan-enabled class.
- How does @SpringBootTest(classes=...) relate to @ContextConfiguration(classes=...)?@SpringBootTest's classes attribute is Spring Boot's convenience wrapper over the underlying Spring TestContext @ContextConfiguration mechanism. Both explicitly designate configuration classes and disable auto-discovery; @SpringBootTest layers Boot conventions (webEnvironment, properties, Boot bootstrapper) on top.
saying these in an interview costs you the question
- Believing classes = MyConfig.class still runs component scanning and auto-configuration automatically
- Confusing @TestConfiguration (additive) with classes (replaces discovery)
- Thinking classes changes only the environment/properties, not which beans load