Endpoint Testing & Assertions
Actually asserting on endpoints: MockMvc and its AssertJ successor, WebTestClient, JSON assertions, result handlers, REST Docs, security test support and TestRestTemplate. This is where most day-to-day Spring test code is written.
part ofSpring Frameworkoverview, primer and where to startread it →on this pageshowhide
explore
- MockMvc API5 questions
- MockMvcTester (AssertJ)5 questions
- WebTestClient5 questions
- JSONPath & Content Assertions5 questions
- Result Handlers & Debugging5 questions
- Spring REST Docs5 questions
- Spring Security Test Support5 questions
- TestRestTemplate5 questions
questions
page 2 of 2Compare @WithMockUser, @WithUserDetails, and @WithSecurityContext. When do you need each?
basics
~20 s@WithMockUser fabricates a simple principal from annotation attributes. @WithUserDetails loads a real principal via your UserDetailsService bean by username, so the principal is your actual UserDetails type. @WithSecurityContext is the extensible base that lets you build a fully custom SecurityContext/Authentication via a factory.
Beyond jsonPath, what body-assertion and result-extraction options does WebTestClient offer, and when would you use expectBody(Class) vs expectBodyList vs returnResult?
basics
~20 sexpectBody(Class) decodes one object; expectBodyList(Class) decodes an array to a List; expectBody() (untyped) gives jsonPath/json(...) assertions on raw JSON; returnResult(Class) exits the fluent chain to get the decoded body (a Flux for streaming) for custom assertions.
When do you use andReturn/MvcResult, how do you test async controller methods, and what are MockMvc's fundamental limitations?
basics
~20 sandReturn() gives you the MvcResult for custom assertions on the raw response. For async endpoints (returning DeferredResult/Callable/CompletableFuture), first andExpect(request().asyncStarted()), then re-dispatch with asyncDispatch(mvcResult). MockMvc's key limit: it runs the DispatcherServlet in-memory, not a real HTTP server.
At scale, how do you keep Spring REST Docs maintainable — reducing per-test boilerplate, keeping constraints/docs in sync, and what tradeoffs does the test-driven-docs approach carry?
basics
~20 sCentralize preprocessors and URI config as defaults, extract reusable snippet/descriptor helpers, drive validation docs from Bean Validation via ConstraintDescriptions, and use snippet templates for consistency. The tradeoff: docs require and depend on maintained tests, and drift breaks the build (intentionally).
A team's MockMvc POST tests intermittently fail with 403 despite @WithMockUser, and their 'anonymous access returns 401' test passes even after they broke config. What test-support pitfalls explain this?
basics
~20 sThe 403 comes from missing CSRF tokens on mutating requests — @WithMockUser authenticates but doesn't add one; they must use .with(csrf()). The false-passing test likely tests without wiring Spring Security into MockMvc (no apply(springSecurity())) or a @WebMvcTest with mocked/absent filter chain, so security isn't actually enforced.
When would you choose TestRestTemplate versus WebTestClient (and how does MockMvc fit) for testing web endpoints?
basics
~20 sUse TestRestTemplate for blocking, real-HTTP integration tests in a classic MVC app — simple, imperative, RestTemplate-style API. Use WebTestClient for its fluent assertion DSL, for reactive/WebFlux apps, or when you want one client that can bind to a live server, MockMvc, or controllers. MockMvc tests the MVC stack without a real socket.
What are the subtle traps with JSONPath number typing, and the difference between `exists`/`doesNotExist`/`isEmpty`/`isNotEmpty`?
basics
~20 sJsonPath maps small JSON integers to Integer and decimals to Double, so .value(1L) fails against 1. exists/doesNotExist test key presence; isEmpty/isNotEmpty test whether a present value is null/empty vs populated. A present-but-null field exists AND isEmpty.
Explain MockMvcTester's lazy exchange model and when you'd adopt it versus classic MockMvc or WebTestClient.
basics
~20 sThe request builder is an AssertJ AssertProvider, so the request only runs when you call assertThat(...) or .exchange(). Adopt MockMvcTester for readable AssertJ servlet-slice tests; keep classic MockMvc where it's already entrenched; use WebTestClient for real-HTTP/WebFlux or full-stack tests.
How would you standardize MockMvc debugging and security across a large test suite using result handlers, `alwaysDo`, and `apply(springSecurity())` — and what are the trade-offs?
basics
~10 sBuild a shared MockMvc via a base class or MockMvcBuilderCustomizer: apply(springSecurity()) for security plus alwaysDo(log()) for uniform, DEBUG-gated diagnostics. Keep global alwaysExpect minimal and add custom ResultHandlers only for cross-cutting captures.
As a tech lead, how do you decide between mock-server and running-server WebTestClient tests, and what pitfalls (timeouts, fidelity, security) do you watch for?
basics
~10 sUse fast mock-server tests (bindToController/context, webEnvironment MOCK) for most controller coverage; reserve slower running-server tests (RANDOM_PORT) for transport, filter-ordering, and true end-to-end concerns. Watch response timeouts, hidden config gaps, and security-context wiring.
showing 31–40 of 40