Testing has scored 100% → 100% → 33% → 60% → 75% across your last five papers. That is not a knowledge problem, it is a coverage problem: you know the headline annotations and guess at the edges. These thirteen show exactly where the edges are — and four of them are one table: which of the four configuration annotations adds to the context and which one silently replaces it.
One genuinely good sign. This bank was full of invented names —
@TestContext and MockBeanAutoconfiguration were both offered, and both were
correctly rejected. Fabricated names peaked at eleven on attempt #10 and are now
zero here. That failure mode is fixed. What is left is the opposite problem: ticking too few boxes
(4 of 13) and reading past the word "NOT" (2 of 13).
Four of the thirteen are this table. It is the single highest-value thing on this page.
| Annotation | Module | Component-scanned? | Effect on a Boot test context |
|---|---|---|---|
nested @Configuration(a static inner class in the test) | spring-context | yes — found as the primary config | REPLACES the application's configuration. Auto-configuration and component scanning disappear. |
@TestConfiguration | spring-boot-test | no — meta-annotated @TestComponent, excluded from the primary search | ADDS beans on top of the discovered configuration. |
@SpringBootConfiguration | spring-boot | — | The marker the bootstrapper searches upward for. Meta-present on @SpringBootApplication. |
@ContextConfiguration | spring-test | — | Plain Spring TestContext wiring. Not needed in a Boot test — @SpringBootTest does discovery itself. |
One sentence and you have the table: the annotation with "Test" in the name is the additive one; the plain one is the destructive one. Your instinct was the exact reverse, on two separate questions.
@SpringBootTest with no classes = ... — how the context is found:
test class package com.example.service
│ SpringBootTestContextBootstrapper
│ → SpringBootConfigurationFinder walks UP
▼
com.example.service → nothing
com.example → @SpringBootApplication ✔ ← used as the ROOT config
(meta-annotated @SpringBootConfiguration)
then, and only then:
nested @TestConfiguration in the test → MERGED in as extra beans
nested plain @Configuration in the test → used INSTEAD, walk never happens
Two failure messages worth memorising:
a test in a package above the app class gives Unable to find a @SpringBootConfiguration;
two candidate classes on the classpath give Found multiple @SpringBootConfiguration annotated classes.
Both are fixed with @SpringBootTest(classes = Application.class).
Three of the thirteen are @WebMvcTest. Every one of them is answered by a single column here.
@SpringBootTest | @WebMvcTest | @DataJpaTest | |
|---|---|---|---|
| Context loaded | the whole thing | web layer only | JPA layer only |
MockMvc | only with @AutoConfigureMockMvc | auto-configured | no |
TestRestTemplate | yes — with RANDOM_PORT / DEFINED_PORT | NO | no |
| Real HTTP server | only RANDOM_PORT / DEFINED_PORT | never | never |
@Service / @Component | loaded | NOT loaded — @MockBean them | not loaded |
@Repository | loaded | not loaded | loaded |
| Flyway / Liquibase | runs | n/a | runs |
| Speed | slowest | fast | fast |
What @WebMvcTest auto-configures —
the list the exam draws from: MockMvc · @Controller ·
@ControllerAdvice · @JsonComponent · Converter /
GenericConverter · Filter · WebMvcConfigurer ·
HandlerMethodArgumentResolver · Spring Security when it is on the classpath. It is also
meta-annotated @ExtendWith(SpringExtension.class).
The only thing on that list you will be offered as a false option is TestRestTemplate, because
it needs a real port.
Q42 asked which wins. You picked OS environment variables, which is the right answer to the runtime version of the question — but this stem was about tests.
lowest
1 SpringApplication.setDefaultProperties(...)
2 application.properties / application.yml
3 application-{profile}.properties ← profile-specific
4 OS environment variables ← your answer
5 command-line arguments ← the winner at RUNTIME
6 @TestPropertySource ← the winner IN A TEST
7 TestPropertyValues set programmatically
highest
Two answers, one ladder.
"Highest precedence" in a running application = command-line arguments.
"Highest precedence" in a test = @TestPropertySource.
Read the stem for the word test before you answer.
@Mock vs @MockBeanOne miss, but this pair is asked in nearly every paper.
| Annotation | Comes from | What it does | What makes it work |
|---|---|---|---|
@Mock | Mockito | Creates a mock and assigns it to the field. Not in the Spring context. | @ExtendWith(MockitoExtension.class) (JUnit 5) · @RunWith(MockitoJUnitRunner.class) (JUnit 4) · or MockitoAnnotations.openMocks(this) |
@MockBean | Spring Boot Test | Replaces the bean of that type in the ApplicationContext. | Any Spring Boot test annotation — the MockitoPostProcessor is registered automatically |
@Spy | Mockito | Wraps a real instance with spy semantics | same as @Mock |
@SpyBean | Spring Boot Test | Wraps an existing context bean with spy semantics | same as @MockBean |
JUnit knows nothing about @Mock. It is a Mockito
annotation; something has to scan for it. That is the whole of Q18.
And @Mock inside a @SpringBootTest does not reach the context — only
@MockBean does. Bonus fact: every distinct @MockBean configuration creates a
fresh context, which is why over-using it makes a suite crawl.
Q25 asked which statement is NOT true. Q46 asked which is not correct. On both you selected a statement that was true — which is to say, you answered the question that was not being asked. This is now the tenth and eleventh polarity slip across your papers and clinics, and it is worth more marks than any single topic on this page.
The mechanical fix, and it costs eight seconds: when the stem contains NOT, except, false or incorrect, write T or F beside every option first, then pick the F. Do not try to hold the inversion in your head while you read — that is exactly when it flips back.
And note Q46's answer: "None of the above." All three
listed statements about @WebMvcTest were true, so the option that is not correct was the
catch-all. "None of the above" on a NOT-question means every listed statement is true. Do not dismiss it
as filler.
On Q2, Q24, Q34 and Q48 every box you ticked was right. You simply stopped ticking too early. Q48 in particular had all four options correct — the eighth "everything is true" question in this series.
The fix is the same one that took MVC from 50% to 100%: rule each option true or false on its own merits, then tick every true one. Do not ask "which is the best answer" on a multi-select — there is no best, only true and false. If a stem says "select one or more", the expected count is frequently three or four, not two.
A third of the bank, and all four are master table 1.
@TestConfiguration vs nested @Configuration@TestConfiguration adds. A plain nested @Configuration replaces.@TestConfiguration replaces the primary configuration;
nested @Configuration is an addition." That is the correct statement read
backwards. The word "Test" marks the safe, additive one.@TestConfiguration is meta-annotated with @TestComponent, which
excludes it from the bootstrapper's search for a primary configuration — so the app's real config is still found,
and the test class's beans are merged on top. A plain nested @Configuration is a valid
primary candidate, so the search stops there and your application configuration never loads.
@SpringBootTest
class MyTest {
@TestConfiguration // additive — app config still loads
static class Extra {
@Bean Clock testClock() { return Clock.fixed(Instant.EPOCH, ZoneOffset.UTC); }
}
}
spring.main.allow-bean-definition-overriding=true (Boot 2.1+).src/test/java same fact as Q1@TestConfiguration — because it is not picked up by component scanning@Configuration. It works, but it is picked
up by component scanning, so it leaks into every test that scans that package. That is the exact reason
@TestConfiguration exists.Two questions, one fact, missed both times in opposite directions — Q1 you said
@TestConfiguration replaces, Q7 you reached for @Configuration instead of it.
| Component-scanned | Intended for | |
|---|---|---|
@Configuration | yes — picked up automatically | main application config |
@TestConfiguration | no — nested, or @Imported explicitly | test-only beans |
@TestConfiguration class must be brought in with
@Import(MyTestConfig.class). A nested one is picked up automatically by the test that owns it.@SpringBootConfiguration itself@TestConfiguration to point at packages to scan".
@TestConfiguration registers extra beans; it declares no scan packages and does
no discovery.If the @SpringBootApplication class sits in the root package and the tests mirror
that package structure, discovery is automatic. SpringBootTestContextBootstrapper runs
SpringBootConfigurationFinder, which searches upward from the test's package for the first
@SpringBootConfiguration, and uses its @ComponentScan and
@EnableAutoConfiguration exactly as in production.
| Scenario | What you do |
|---|---|
| Standard app, tests under the same root package | Nothing |
| More than one candidate main class | @SpringBootTest(classes = Application.class) |
| Narrow the context to one layer | a slice — @WebMvcTest, @DataJpaTest |
| Add a few extra beans | nested @TestConfiguration |
| Fully custom, non-Boot config | @ContextConfiguration(classes = ...) + @ExtendWith(SpringExtension.class) |
@ComponentScan to a Boot test is not just unnecessary, it is
harmful — it duplicates scanning and can register beans twice.ApplicationContext per unique
configuration and reuses it across every test that asks for the same one. That caching is the single biggest
reason Spring test suites are tolerable. The correct statement — "context configuration can be
inherited from the superclass" — you left unticked.The four TestContext facts this question rotates through:
@MockBean, @TestPropertySource and @ActiveProfiles all fragment the cache).@Autowired in the test class. You never need context.getBean().@ContextConfiguration and @ActiveProfiles are inherited from a superclass, which is how abstract base test classes work.@ContextConfiguration need not name a file; conventions and nested @Configuration classes are enough.@WebMvcTest 3 missesThe same annotation three times, and two of them were only wrong because of the word "NOT".
@WebMvcTest auto-configure? under-selectionMockMvc, @ControllerAdvice, WebMvcConfigurer — not TestRestTemplateTestRestTemplate — that part was right.TestRestTemplate makes real HTTP calls, so it needs a real server. Only
@SpringBootTest(webEnvironment = RANDOM_PORT) (or DEFINED_PORT) starts one.
@WebMvcTest never starts a server — it dispatches through MockMvc instead.
MockMvc = no server. TestRestTemplate = real
server. If a stem mentions a port, it cannot be a slice test.@WebMvcTest"All four options were about things Spring genuinely does: Mockito integrates via
@Mock and @MockBean; the TestContext Framework is real; it supports JUnit 4
(@RunWith(SpringRunner.class)), JUnit 5 (@ExtendWith(SpringExtension.class))
and TestNG. The single planted falsehood was a denial of @WebMvcTest.
@WebMvcTest is not correct? polarity@WebMvcTest is meta-annotated with
@ExtendWith(SpringExtension.class)." True — that is precisely how a slice
test hooks into JUnit 5.The three true statements were: it auto-configures Spring MVC infrastructure; it is
meta-annotated with @ExtendWith(SpringExtension.class); it auto-configures MockMvc.
With nothing false among them, the catch-all becomes the answer.
MockHttpServletRequest and friendsspring-test ships mock implementations of the Servlet API in
org.springframework.mock.web, so you can exercise controllers and filters with no container at all:
| Mock class | Simulates |
|---|---|
MockHttpServletRequest | the HTTP request |
MockHttpServletResponse | the HTTP response |
MockHttpSession | the HTTP session |
MockServletContext | the servlet context |
Flyway is auto-configured whenever it is on the classpath, and its migrations run as the
ApplicationContext starts — before any test method executes.
| Aspect | Behaviour |
|---|---|
| When migrations run | automatically, on ApplicationContext startup |
| Naming convention | V{version}__{description}.sql — two underscores |
| Which database | whatever the active profile configures (typically H2 in application-test.properties) |
| A broken script | the context fails to load, so the test fails before it runs |
@SpringBootTest | does not disable Flyway — you must set spring.flyway.enabled=false yourself |
@DataJpaTest | also runs Flyway/Liquibase, with a lighter context |
spring-boot-starter-test pull in? all four correctThe full contents of the starter, which is worth knowing as a list because the exam samples from it:
MockMvc, the TestContext Framework, transactional test support@SpringBootTest, the slicesassertThat(x).isEqualTo(y))@ActiveProfiles under-selectionWith @ActiveProfiles({"test", "integration"}):
| What happens | Detail |
|---|---|
| Property files | application-test.properties and application-integration.properties are both loaded and merged |
| Conflicting key | the later-listed profile wins — here, integration |
@Profile beans | beans for both profiles are created |
| How many profiles | any number — there is no limit of two |
| Conflict warning | none — Spring resolves silently by precedence |
@TestPropertySource(properties = "key=value") — it outranks every profile file.@TestPropertySource — above environment variables and command-line arguments@TestPropertySource, which sits above both environment variables and
command-line arguments within a test context.See master table 3 for the full ladder. The distinction the exam is testing:
command-line arguments win at runtime; @TestPropertySource wins in a test.
@SpringBootTest
@TestPropertySource(properties = "my.custom.value=test123")
class MyTest {
@Value("${my.custom.value}") String value; // "test123" — beats everything else
}
@Mock to work?MockitoExtension (JUnit 5) or MockitoJUnitRunner (JUnit 4) — or call openMocks(this)@Mock is supported by default by JUnit."
@Mock is a Mockito annotation. JUnit has never heard of it — something
has to scan the fields and call MockitoAnnotations.openMocks(this).See master table 4 for the full @Mock/@MockBean split. The three ways
to activate @Mock:
@ExtendWith(MockitoExtension.class) // JUnit 5 — preferred
@RunWith(MockitoJUnitRunner.class) // JUnit 4
MockitoAnnotations.openMocks(this); // manual, in @BeforeEach
The manual route works but loses strict stubbing — the runner and the extension both fail the test on unused stubs, which the manual call does not.
MockBeanAutoconfiguration here. Fabricated names are no longer catching you — that was the
single biggest error mode two papers ago.Reading this page will not move the score; retrieving from it will. Run the thirty-five below, then come back tomorrow and run them again.
@TestConfiguration ADDS; nested plain @Configuration REPLACES. "Test" = the safe onesrc/test/java get @TestConfiguration — it is not component-scanned, so it cannot leak@SpringBootConfiguration. Never add @ComponentScan@Autowired, never getBean()@WebMvcTest auto-configures MockMvc, @ControllerAdvice, WebMvcConfigurer, @JsonComponent, converters, filters — but never TestRestTemplateMockMvc = no server. TestRestTemplate = real server, so RANDOM_PORT or DEFINED_PORT. @SpringBootTest defaults to MOCK@Mock needs MockitoExtension / MockitoJUnitRunner / openMocks(this). JUnit does not know it exists@Mock = a field. @MockBean = a context bean, and every distinct @MockBean set builds a fresh context@ActiveProfiles takes any number; the LATER profile wins a conflict; there is no warning@TestPropertySource in a test. Read the stem for the word "test"V1__Name.sql with two underscores; a broken script fails the context; @SpringBootTest does not disable itorg.springframework.mock.web servlet mocksspring-boot-starter-test brings everything — JUnit, Spring Test, Boot Test, AssertJ, Hamcrest, Mockito, JSONassert, JsonPath, XMLUnit@WebMvcTest row is the one
the exam samples from repeatedly.
(4) Drill, don't re-read. Testing is the fifth clinic. Its 100% → 33% swing is a coverage problem, and
coverage only comes from rotating all five clinics — 20 minutes before your next attempt beats reading one new page.
@SpringBootTest vs @WebMvcTest vs @DataJpaTest, or "drill all five
clinics" for the full rotation. Spring Core is now the only section without a clinic — point me at a
Core bank whenever you like.