skip to content

@WebFluxTest & @RestClientTest

@WebFluxTest gives reactive controllers with WebTestClient, and @RestClientTest tests outbound calls against a mock server with recorded expectations. Interviewers ask how you test a client without hitting the real service.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

questions

5

What is @WebFluxTest and what does it auto-configure for you?

level: juniorimportance: must knowfreq 62%

answer

  1. Reactive web slice, not full context
  2. Auto-configures WebTestClient (in-memory, no port)
  3. Controllers + advice + filters only
  4. Mock services with @MockBean/@MockitoBean
  5. WebFlux-only — MVC uses @WebMvcTest

basics

~20 s

@WebFluxTest is a sliced Spring Boot test that loads only the reactive web layer — your @RestController/@Controller and WebFlux infrastructure — not the whole app. It auto-configures a WebTestClient so you can call your endpoints in tests.

solid answer

~40 s

@WebFluxTest is a Spring Boot test slice annotation for reactive (Spring WebFlux) controllers. Instead of starting the full ApplicationContext, it loads only the web layer: your @Controller/@RestController beans, @ControllerAdvice, WebFilter, converters, and WebFlux auto-configuration. It deliberately excludes @Component, @Service, and @Repository beans, so collaborators are provided via @MockBean (or, in newer Boot, @MockitoBean). It auto-configures a WebTestClient bound to the routing/handler infrastructure — no real HTTP server or port — letting you fluently issue requests and assert status, headers and JSON body. You can narrow it further with @WebFluxTest(controllers = MyController.class). It's fast and focused, ideal for testing request mapping, validation, serialization and error handling in isolation from the service and persistence layers.

code

java · 21 lines
java
@WebFluxTest(GreetingController.class)
class GreetingControllerTest {

    @Autowired
    WebTestClient webTestClient; // auto-configured, bound in-memory

    @MockBean // or @MockitoBean on Boot 3.4+
    GreetingService greetingService;

    @Test
    void returnsGreeting() {
        given(greetingService.greet("Ada"))
            .willReturn(Mono.just(new Greeting("Hello, Ada")));

        webTestClient.get().uri("/greet/Ada")
            .exchange()
            .expectStatus().isOk()
            .expectBody()
            .jsonPath("$.message").isEqualTo("Hello, Ada");
    }
}

go deeper

for a junior

Know it's a fast test that loads only reactive controllers and gives you a WebTestClient.

for a middle

Know exactly which beans are in/out of the slice and that collaborators need @MockBean/@MockitoBean.

for a senior

Explain in-memory binding, security interactions, controller scoping, and reactive materialization.

for a principal

Frame slice tests within a testing pyramid: when a slice suffices vs a full @SpringBootTest, and cost/coverage tradeoffs.

## What it is `@WebFluxTest` is a **test slice** annotation from `org.springframework.boot.test.autoconfigure.web.reactive`. A *test slice* means Spring Boot starts a **minimal ApplicationContext** containing only the beans relevant to one layer — here, the **reactive web layer (Spring WebFlux)** — instead of the entire application. This keeps the test fast and focused. ## What gets loaded With `@WebFluxTest`, Spring Boot registers: - Your `@Controller` / `@RestController` beans (all of them, or only the ones you name). - `@ControllerAdvice` / `@RestControllerAdvice` exception handlers. - `WebFilter` beans, `HttpMessageReader`/`HttpMessageWriter` (Jackson JSON codecs), `Converter`/`Formatter`, and WebFlux auto-configuration. - Spring Security's WebFlux config if it's on the classpath. ## What is NOT loaded It **excludes** regular `@Component`, `@Service`, `@Repository`, `@Configuration` beans that aren't part of the web slice. So if your controller depends on a `GreetingService`, that bean does **not** exist in the context — you must supply it with **`@MockBean`** (classic) or **`@MockitoBean`** (Spring Framework 6.2+/Boot 3.4+). Forgetting this causes a context-startup failure: *No qualifying bean of type ...*. ## WebTestClient auto-configuration The headline feature: `@WebFluxTest` auto-configures a **`WebTestClient`** and injects it via `@Autowired`. `WebTestClient` is a non-blocking, reactive test client. In a slice test it is **bound to the WebFlux handler infrastructure in-memory** (no real network socket, no port). It exposes a fluent API: `.get().uri(...)`, `.exchange()`, then `.expectStatus()`, `.expectHeader()`, `.expectBody(Type.class)`, `.expectBody().json(...)`, `.jsonPath(...)`. ## Scoping to specific controllers `@WebFluxTest(controllers = MyController.class)` or `@WebFluxTest(MyController.class)` loads only that controller, keeping the context tiny and avoiding unrelated controllers' dependencies. ## Reactive return types Because it's WebFlux, controller methods typically return `Mono<T>` or `Flux<T>`. `WebTestClient` transparently subscribes and materializes the response, so your assertions look synchronous even though the pipeline is reactive. ## Gotchas - **Not for Spring MVC.** For blocking MVC controllers use `@WebMvcTest` + `MockMvc`. `@WebFluxTest` is WebFlux-only. - **Security surprises.** If Spring Security is present, endpoints may return 401/403 in the slice. Use `@WithMockUser` / test security config or configure `WebTestClient` mutators. - **Missing collaborators** must be mocked; the slice won't scan your services. - **No persistence.** Repositories/`DatabaseClient`/R2DBC beans are not loaded. ## When to use Use `@WebFluxTest` to verify controller-level concerns — routing, path/query binding, validation, JSON (de)serialization, status codes, headers, error mapping — quickly and in isolation, mocking the service layer beneath.

  • Your controller calls a GreetingService. What happens in a @WebFluxTest if you don't declare it?
    The context fails to start with a 'No qualifying bean of type GreetingService' error, because the slice does not load @Service beans. You must provide it via @MockBean/@MockitoBean (or import a real config).
  • Does WebTestClient in a @WebFluxTest open a real HTTP port?
    No. By default it binds directly to the WebFlux handler/router infrastructure in memory (bindToApplicationContext), so there's no server socket or random port — it's fast and avoids network flakiness.

saying these in an interview costs you the question

  • Saying @WebFluxTest loads the whole application context
  • Claiming it works for Spring MVC controllers with MockMvc
  • Thinking @Service/@Repository beans are auto-loaded into the slice
  • Believing WebTestClient starts a real server on a random port by default

context

open as a page

What does @RestClientTest do, and how do you assert against outgoing HTTP calls with MockRestServiceServer?

level: middleimportance: must knowfreq 55%

basics

~20 s

@RestClientTest is a slice for testing a component that calls a remote API via RestTemplate or RestClient. It auto-configures a MockRestServiceServer that intercepts outgoing requests, lets you set up expected requests and canned responses, and verifies they were called.

open as a page

In MockRestServiceServer, how do you control expected call counts and request ordering, and test retries or multiple calls?

level: seniorimportance: should knowfreq 32%

basics

~20 s

Use ExpectedCount in server.expect(...) — like once(), times(n), min(n), max(n), manyTimes(), never() — to say how many times a request should occur. By default expectations must happen in the order recorded; you can build an unordered server (ignoreExpectOrder) so requests match in any order, which is useful for retries or concurrent calls.

open as a page

How is WebTestClient bound in a @WebFluxTest, and how do you handle Spring Security in the slice?

level: seniorimportance: should knowfreq 40%

basics

~20 s

In @WebFluxTest, WebTestClient binds directly to the in-memory WebFlux handler (no server/port), so tests are fast and deterministic. If Spring Security is on the classpath it also applies in the slice, so you use test security config or mutators like mockUser() to authenticate requests.

open as a page

How do you decide between @WebFluxTest/@RestClientTest slices and a full @SpringBootTest, and what are the tradeoffs?

level: principalimportance: should knowfreq 25%

basics

~20 s

Use slices (@WebFluxTest, @RestClientTest) for fast, focused unit-ish tests of one layer with collaborators mocked. Use @SpringBootTest when you need the real wired application — cross-layer flows, real security, real transport, or integration with the database or a running server. Slices are cheaper but cover less.

open as a page