What does @SpringJUnitConfig do, and how does it differ from @SpringJUnitWebConfig?
answer
- SpringJUnitConfig = SpringExtension + ContextConfiguration
- WebConfig adds @WebAppConfiguration => WebApplicationContext
- value/classes aliases classes; locations for XML
- Web variant enables request/session scope + MockMvc webAppContextSetup
- Core Spring, not Boot
basics
~10 s@SpringJUnitConfig is a composed annotation that combines @ExtendWith(SpringExtension.class) with @ContextConfiguration in one line. @SpringJUnitWebConfig does the same but also adds @WebAppConfiguration, giving you a WebApplicationContext for web-layer tests.
solid answer
~30 sBoth are convenience composed annotations from org.springframework.test.context.junit.jupiter. @SpringJUnitConfig = @ExtendWith(SpringExtension.class) + @ContextConfiguration. Its value/classes attribute is an alias for @ContextConfiguration's classes, and it also exposes a locations attribute for XML. So @SpringJUnitConfig(AppConfig.class) registers the extension and loads AppConfig in one annotation. @SpringJUnitWebConfig additionally layers @WebAppConfiguration, so the loaded context is a WebApplicationContext with a MockServletContext — required when the beans need servlet-environment things (e.g. request/session scope, or wiring for MockMvc via the standaloneSetup/webAppContextSetup path). It also lets you set the resource base path. Use @SpringJUnitConfig for plain context tests and @SpringJUnitWebConfig when the test needs a web application context.
code
java · 18 lines// Plain context test
@SpringJUnitConfig(AppConfig.class)
class OrderServiceTest {
@Autowired OrderService orderService;
@Test void loads() { assertThat(orderService).isNotNull(); }
}
// Web context test (WebApplicationContext + MockMvc)
@SpringJUnitWebConfig(WebConfig.class)
class GreetingControllerTest {
MockMvc mockMvc;
@BeforeEach void setUp(WebApplicationContext wac) {
this.mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
}
@Test void getGreeting() throws Exception {
mockMvc.perform(get("/greeting")).andExpect(status().isOk());
}
}go deeper
Know @SpringJUnitConfig is a shortcut that bundles the extension and @ContextConfiguration.
Explain the aliased attributes and that the Web variant adds @WebAppConfiguration for a WebApplicationContext.
Discuss when to pick these over @SpringBootTest/slices and the servlet-scope/MockMvc implications of the web variant.
Reason about composed-annotation design (@AliasFor), default nested-config detection, and boundaries between core-Spring and Boot test infrastructure.
## Composed annotations Spring provides two 'batteries-included' meta-annotations so you don't hand-assemble the extension plus configuration every time. Both live in `org.springframework.test.context.junit.jupiter`. ### `@SpringJUnitConfig` It is meta-annotated with: - `@ExtendWith(SpringExtension.class)` — wires JUnit 5 to the TestContext Framework. - `@ContextConfiguration` — declares how to build the `ApplicationContext`. Attribute aliases (via `@AliasFor`): - `value` / `classes` → `@ContextConfiguration#classes` (Java `@Configuration` classes or component classes). - `locations` → `@ContextConfiguration#locations` (XML/Groovy resource locations). - `initializers`, `inheritLocations`, `inheritInitializers`, `name` also pass through. So these are equivalent: ```java @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = AppConfig.class) ``` and ```java @SpringJUnitConfig(AppConfig.class) ``` ### `@SpringJUnitWebConfig` Same as above **plus** `@WebAppConfiguration`. The result is that the loaded context is a **`WebApplicationContext`** backed by a `MockServletContext`, rather than a plain `ApplicationContext`. Why that matters: - Enables **web-specific bean scopes**: `request`, `session`, `application`. - Provides a `ServletContext` so beans expecting the servlet environment can be created. - Is the standard base for **MockMvc** tests wired through `MockMvcBuilders.webAppContextSetup(webApplicationContext)`. Extra attribute: `resourcePath` (alias for `@WebAppConfiguration#value`) sets the base path for web resources (default `src/main/webapp`). `@SpringJUnitWebConfig` also carries the same `value`/`classes`/`locations` aliases for `@ContextConfiguration`. ## When to use which - **`@SpringJUnitConfig`** — service/repository/plain bean tests where no servlet environment is needed. - **`@SpringJUnitWebConfig`** — controller/web-layer tests, request/session-scoped beans, or full-context MockMvc tests. ## Relationship to Spring Boot These are **core Spring Framework** annotations (not Boot). Spring Boot users usually reach for `@SpringBootTest` (full auto-configured context) or slice annotations (`@WebMvcTest`, `@DataJpaTest`). Those Boot annotations do **not** compose `@SpringJUnitConfig`; they compose `@ExtendWith(SpringExtension.class)` with Boot's own configuration mechanisms. Use `@SpringJUnitConfig`/`@SpringJUnitWebConfig` in plain-Spring projects or when you want an explicit, minimal context without Boot's auto-configuration. ## Gotchas - `@SpringJUnitConfig(MyConfig.class)` uses `value`; if you also try to set `locations` you're mixing XML and Java config — allowed but be deliberate. - Passing **no** classes and no locations triggers the default detection of a static nested `@Configuration` class inside the test — a common convenience. - `@WebAppConfiguration` (hence `@SpringJUnitWebConfig`) requires `spring-web` on the classpath.
- You have @SpringJUnitConfig with no classes and no locations argument. What does Spring load?It falls back to @ContextConfiguration's default detection: a static nested @Configuration class declared inside the test class. If none exists, context loading fails.
- Why would a request-scoped bean fail under @SpringJUnitConfig but work under @SpringJUnitWebConfig?Request/session scopes require a web application context with a servlet environment. @SpringJUnitConfig loads a plain ApplicationContext with no such scopes registered, so resolving a request-scoped bean throws; @SpringJUnitWebConfig adds @WebAppConfiguration which provides a WebApplicationContext + MockServletContext registering those scopes.
saying these in an interview costs you the question
- Claiming @SpringJUnitConfig is a Spring Boot annotation
- Saying @SpringJUnitWebConfig only changes the base resource path (it changes the context type)
- Thinking you still need to add @ExtendWith(SpringExtension.class) alongside these composed annotations