skip to content

What does @SpringJUnitConfig do, and how does it differ from @SpringJUnitWebConfig?

level: middleimportance: should knowfreq 55%

answer

  1. SpringJUnitConfig = SpringExtension + ContextConfiguration
  2. WebConfig adds @WebAppConfiguration => WebApplicationContext
  3. value/classes aliases classes; locations for XML
  4. Web variant enables request/session scope + MockMvc webAppContextSetup
  5. 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 s

Both 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
java
// 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

for a junior

Know @SpringJUnitConfig is a shortcut that bundles the extension and @ContextConfiguration.

for a middle

Explain the aliased attributes and that the Web variant adds @WebAppConfiguration for a WebApplicationContext.

for a senior

Discuss when to pick these over @SpringBootTest/slices and the servlet-scope/MockMvc implications of the web variant.

for a principal

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

context