Spring TestContext Framework for comprehensive integration testing of Spring applications
Spring's web testing support provides MockMvc framework for testing Spring MVC controllers without starting a full HTTP server. It offers fluent API for request building, response assertions, and integrates seamlessly with the TestContext Framework.
The main entry point for server-side Spring MVC testing, providing request execution and result assertion capabilities.
/**
* Main entry point for server-side Spring MVC test support.
* Provides a fluent API to perform requests and verify results.
*/
public final class MockMvc {
/**
* Perform a request and return a type that allows chaining further actions,
* such as asserting expectations, on the result.
* @param requestBuilder used to prepare the request to execute
* @return an instance of ResultActions (never null)
* @throws Exception if an exception occurs during request execution
*/
public ResultActions perform(RequestBuilder requestBuilder) throws Exception;
}
/**
* Factory class for creating MockMvc instances.
*/
public final class MockMvcBuilders {
/**
* Build a MockMvc instance using the given WebApplicationContext.
* @param context the WebApplicationContext to use
* @return a MockMvcBuilder to further configure the MockMvc instance
*/
public static DefaultMockMvcBuilder webAppContextSetup(WebApplicationContext context);
/**
* Build a MockMvc instance by registering one or more @Controller instances
* and configuring Spring MVC infrastructure programmatically.
* @param controllers one or more @Controller instances to test
* @return a StandaloneMockMvcBuilder to further configure the MockMvc instance
*/
public static StandaloneMockMvcBuilder standaloneSetup(Object... controllers);
/**
* Build a MockMvc instance using the given RouterFunction.
* @param routerFunction the RouterFunction to use
* @return a MockMvcBuilder to further configure the MockMvc instance
*/
public static RouterFunctionMockMvcBuilder routerFunction(RouterFunction<?> routerFunction);
}Factory and builder classes for creating HTTP requests in tests.
/**
* Static factory methods for RequestBuilder instances that create various types of HTTP requests.
*/
public abstract class MockMvcRequestBuilders {
/**
* Create a MockHttpServletRequestBuilder for a GET request.
* @param urlTemplate a URL template; the resulting URL will be encoded
* @param uriVariables zero or more URI variables
* @return the request builder
*/
public static MockHttpServletRequestBuilder get(String urlTemplate, Object... uriVariables);
/**
* Create a MockHttpServletRequestBuilder for a POST request.
* @param urlTemplate a URL template; the resulting URL will be encoded
* @param uriVariables zero or more URI variables
* @return the request builder
*/
public static MockHttpServletRequestBuilder post(String urlTemplate, Object... uriVariables);
/**
* Create a MockHttpServletRequestBuilder for a PUT request.
* @param urlTemplate a URL template; the resulting URL will be encoded
* @param uriVariables zero or more URI variables
* @return the request builder
*/
public static MockHttpServletRequestBuilder put(String urlTemplate, Object... uriVariables);
/**
* Create a MockHttpServletRequestBuilder for a PATCH request.
* @param urlTemplate a URL template; the resulting URL will be encoded
* @param uriVariables zero or more URI variables
* @return the request builder
*/
public static MockHttpServletRequestBuilder patch(String urlTemplate, Object... uriVariables);
/**
* Create a MockHttpServletRequestBuilder for a DELETE request.
* @param urlTemplate a URL template; the resulting URL will be encoded
* @param uriVariables zero or more URI variables
* @return the request builder
*/
public static MockHttpServletRequestBuilder delete(String urlTemplate, Object... uriVariables);
/**
* Create a MockHttpServletRequestBuilder for a HEAD request.
* @param urlTemplate a URL template; the resulting URL will be encoded
* @param uriVariables zero or more URI variables
* @return the request builder
*/
public static MockHttpServletRequestBuilder head(String urlTemplate, Object... uriVariables);
/**
* Create a MockHttpServletRequestBuilder for an OPTIONS request.
* @param urlTemplate a URL template; the resulting URL will be encoded
* @param uriVariables zero or more URI variables
* @return the request builder
*/
public static MockHttpServletRequestBuilder options(String urlTemplate, Object... uriVariables);
/**
* Create a MockMultipartHttpServletRequestBuilder for a multipart request.
* @param urlTemplate a URL template; the resulting URL will be encoded
* @param uriVariables zero or more URI variables
* @return the request builder
*/
public static MockMultipartHttpServletRequestBuilder multipart(String urlTemplate, Object... uriVariables);
/**
* Create a RequestBuilder for an async dispatch from the MvcResult of the request.
* @param mvcResult the result from the request that initiated async processing
* @return the request builder for the async dispatch
*/
public static RequestBuilder asyncDispatch(MvcResult mvcResult);
}
/**
* Default builder for MockHttpServletRequest instances.
*/
public class MockHttpServletRequestBuilder implements ConfigurableSmartRequestBuilder<MockHttpServletRequestBuilder> {
/**
* Add a request parameter to the MockHttpServletRequest.
* @param name the parameter name
* @param values one or more values
* @return this request builder
*/
public MockHttpServletRequestBuilder param(String name, String... values);
/**
* Add multiple request parameters and values.
* @param params the parameters to add
* @return this request builder
*/
public MockHttpServletRequestBuilder params(MultiValueMap<String, String> params);
/**
* Add a header to the request.
* @param name the header name
* @param values one or more header values
* @return this request builder
*/
public MockHttpServletRequestBuilder header(String name, Object... values);
/**
* Add all headers from the given HttpHeaders object.
* @param httpHeaders the HttpHeaders object
* @return this request builder
*/
public MockHttpServletRequestBuilder headers(HttpHeaders httpHeaders);
/**
* Set the content type of the request.
* @param contentType the content type
* @return this request builder
*/
public MockHttpServletRequestBuilder contentType(MediaType contentType);
/**
* Set the Accept header of the request.
* @param mediaTypes one or more media types
* @return this request builder
*/
public MockHttpServletRequestBuilder accept(MediaType... mediaTypes);
/**
* Set the content of the request body.
* @param content the body content
* @return this request builder
*/
public MockHttpServletRequestBuilder content(String content);
/**
* Set the content of the request body as a byte array.
* @param content the body content
* @return this request builder
*/
public MockHttpServletRequestBuilder content(byte[] content);
/**
* Add a cookie to the request.
* @param cookies one or more cookies
* @return this request builder
*/
public MockHttpServletRequestBuilder cookie(Cookie... cookies);
/**
* Set the locale of the request.
* @param locale the locale
* @return this request builder
*/
public MockHttpServletRequestBuilder locale(Locale locale);
/**
* Set the character encoding of the request.
* @param encoding the character encoding
* @return this request builder
*/
public MockHttpServletRequestBuilder characterEncoding(String encoding);
/**
* Apply the given RequestPostProcessor.
* @param postProcessor the post processor to apply
* @return this request builder
*/
public MockHttpServletRequestBuilder with(RequestPostProcessor postProcessor);
}Interfaces and factory classes for asserting the results of MockMvc requests.
/**
* Allows applying actions, such as expectations, on the result of an executed request.
*/
public interface ResultActions {
/**
* Perform an expectation.
* @param matcher the expectation
* @return this ResultActions instance for method chaining
* @throws Exception if the expectation fails
*/
ResultActions andExpect(ResultMatcher matcher) throws Exception;
/**
* Perform multiple expectations.
* @param matchers the expectations
* @return this ResultActions instance for method chaining
* @throws Exception if any expectation fails
*/
ResultActions andExpectAll(ResultMatcher... matchers) throws Exception;
/**
* Perform a general action.
* @param handler the handler to execute
* @return this ResultActions instance for method chaining
* @throws Exception if the action fails
*/
ResultActions andDo(ResultHandler handler) throws Exception;
/**
* Return the result of the executed request for direct access to the results.
* @return the MvcResult
*/
MvcResult andReturn();
}
/**
* Factory for assertions on the result of a request executed through MockMvc.
*/
public abstract class MockMvcResultMatchers {
/**
* Access to request-related assertions.
* @return the RequestResultMatchers instance
*/
public static RequestResultMatchers request();
/**
* Access to response status assertions.
* @return the StatusResultMatchers instance
*/
public static StatusResultMatchers status();
/**
* Access to response header assertions.
* @return the HeaderResultMatchers instance
*/
public static HeaderResultMatchers header();
/**
* Access to response content assertions.
* @return the ContentResultMatchers instance
*/
public static ContentResultMatchers content();
/**
* Access to response body JSON path assertions.
* @param expression the JSON path expression
* @param args arguments to parameterize the JSON path expression with
* @return the JsonPathResultMatchers instance
*/
public static JsonPathResultMatchers jsonPath(String expression, Object... args);
/**
* Access to response body XPath assertions.
* @param expression the XPath expression
* @param args arguments to parameterize the XPath expression with
* @return the XpathResultMatchers instance
*/
public static XpathResultMatchers xpath(String expression, Object... args);
/**
* Access to model-related assertions.
* @return the ModelResultMatchers instance
*/
public static ModelResultMatchers model();
/**
* Access to view-related assertions.
* @return the ViewResultMatchers instance
*/
public static ViewResultMatchers view();
/**
* Access to flash attribute assertions.
* @return the FlashAttributeResultMatchers instance
*/
public static FlashAttributeResultMatchers flash();
/**
* Access to redirect URL assertions.
* @param expectedUrl the expected redirect URL
* @return the ResultMatcher instance
*/
public static ResultMatcher redirectedUrl(String expectedUrl);
/**
* Access to forwarded URL assertions.
* @param expectedUrl the expected forward URL
* @return the ResultMatcher instance
*/
public static ResultMatcher forwardedUrl(String expectedUrl);
/**
* Access to cookie-related assertions.
* @return the CookieResultMatchers instance
*/
public static CookieResultMatchers cookie();
}
/**
* Factory for response status assertions.
*/
public class StatusResultMatchers {
/**
* Assert the response status code is equal to the given status.
* @param status the expected status
* @return the ResultMatcher
*/
public ResultMatcher is(HttpStatus status);
/**
* Assert the response status code is equal to the given integer value.
* @param status the expected status code
* @return the ResultMatcher
*/
public ResultMatcher is(int status);
/**
* Assert the response status code is 200 (OK).
* @return the ResultMatcher
*/
public ResultMatcher isOk();
/**
* Assert the response status code is 201 (Created).
* @return the ResultMatcher
*/
public ResultMatcher isCreated();
/**
* Assert the response status code is 202 (Accepted).
* @return the ResultMatcher
*/
public ResultMatcher isAccepted();
/**
* Assert the response status code is 204 (No Content).
* @return the ResultMatcher
*/
public ResultMatcher isNoContent();
/**
* Assert the response status code is 400 (Bad Request).
* @return the ResultMatcher
*/
public ResultMatcher isBadRequest();
/**
* Assert the response status code is 401 (Unauthorized).
* @return the ResultMatcher
*/
public ResultMatcher isUnauthorized();
/**
* Assert the response status code is 403 (Forbidden).
* @return the ResultMatcher
*/
public ResultMatcher isForbidden();
/**
* Assert the response status code is 404 (Not Found).
* @return the ResultMatcher
*/
public ResultMatcher isNotFound();
/**
* Assert the response status code is 500 (Internal Server Error).
* @return the ResultMatcher
*/
public ResultMatcher isInternalServerError();
}
/**
* Factory for response content assertions.
*/
public class ContentResultMatchers {
/**
* Assert the response content type using a MediaType.
* @param contentType the expected content type
* @return the ResultMatcher
*/
public ResultMatcher contentType(MediaType contentType);
/**
* Assert the response content type as a String.
* @param contentType the expected content type
* @return the ResultMatcher
*/
public ResultMatcher contentType(String contentType);
/**
* Assert the response content encoding.
* @param characterEncoding the expected character encoding
* @return the ResultMatcher
*/
public ResultMatcher encoding(String characterEncoding);
/**
* Assert the response content as a String.
* @param expectedContent the expected content
* @return the ResultMatcher
*/
public ResultMatcher string(String expectedContent);
/**
* Assert the response content matches the given Hamcrest matcher.
* @param matcher the Hamcrest matcher
* @return the ResultMatcher
*/
public ResultMatcher string(Matcher<? super String> matcher);
/**
* Assert the response content as a byte array.
* @param expectedContent the expected content
* @return the ResultMatcher
*/
public ResultMatcher bytes(byte[] expectedContent);
/**
* Assert the response content as JSON.
* @param jsonContent the expected JSON content
* @return the ResultMatcher
*/
public ResultMatcher json(String jsonContent);
/**
* Assert the response content as JSON with strict comparison.
* @param jsonContent the expected JSON content
* @param strict whether to use strict comparison
* @return the ResultMatcher
*/
public ResultMatcher json(String jsonContent, boolean strict);
/**
* Assert the response content as XML.
* @param xmlContent the expected XML content
* @return the ResultMatcher
*/
public ResultMatcher xml(String xmlContent);
}Factory for actions to perform on MockMvc results.
/**
* Static factory methods for ResultHandler instances.
*/
public abstract class MockMvcResultHandlers {
/**
* Print the request and response details to System.out.
* @return the ResultHandler instance
*/
public static ResultHandler print();
/**
* Print the request and response details to the given OutputStream.
* @param stream the target stream
* @return the ResultHandler instance
*/
public static ResultHandler print(OutputStream stream);
/**
* Print the request and response details to the given Writer.
* @param writer the target writer
* @return the ResultHandler instance
*/
public static ResultHandler print(Writer writer);
/**
* Log the request and response details at DEBUG level using the given logger.
* @return the ResultHandler instance
*/
public static ResultHandler log();
}Modern AssertJ-style fluent assertions for MockMvc testing.
/**
* AssertJ-style assertions for MockMvc.
* Provides fluent API for testing Spring MVC applications.
*/
public class MockMvcTester {
/**
* Create a MockMvcTester instance from the given MockMvc.
* @param mockMvc the MockMvc instance
* @return the MockMvcTester instance
*/
public static MockMvcTester create(MockMvc mockMvc);
/**
* Perform a GET request.
* @param uriTemplate the URI template
* @param uriVariables URI variables
* @return the MockMvcRequestSpec for further configuration
*/
public MockMvcRequestSpec get(String uriTemplate, Object... uriVariables);
/**
* Perform a POST request.
* @param uriTemplate the URI template
* @param uriVariables URI variables
* @return the MockMvcRequestSpec for further configuration
*/
public MockMvcRequestSpec post(String uriTemplate, Object... uriVariables);
/**
* Perform a PUT request.
* @param uriTemplate the URI template
* @param uriVariables URI variables
* @return the MockMvcRequestSpec for further configuration
*/
public MockMvcRequestSpec put(String uriTemplate, Object... uriVariables);
/**
* Perform a PATCH request.
* @param uriTemplate the URI template
* @param uriVariables URI variables
* @return the MockMvcRequestSpec for further configuration
*/
public MockMvcRequestSpec patch(String uriTemplate, Object... uriVariables);
/**
* Perform a DELETE request.
* @param uriTemplate the URI template
* @param uriVariables URI variables
* @return the MockMvcRequestSpec for further configuration
*/
public MockMvcRequestSpec delete(String uriTemplate, Object... uriVariables);
}
/**
* AssertJ-style request specification for MockMvc testing.
*/
public class MockMvcRequestSpec {
/**
* Add a request parameter.
* @param name the parameter name
* @param values one or more parameter values
* @return this request spec
*/
public MockMvcRequestSpec param(String name, String... values);
/**
* Add a request header.
* @param name the header name
* @param values one or more header values
* @return this request spec
*/
public MockMvcRequestSpec header(String name, Object... values);
/**
* Set the content type.
* @param contentType the content type
* @return this request spec
*/
public MockMvcRequestSpec contentType(MediaType contentType);
/**
* Set the request content.
* @param content the content
* @return this request spec
*/
public MockMvcRequestSpec content(String content);
/**
* Execute the request and return assertions.
* @return the AbstractMockMvcResultAssert for assertions
*/
public AbstractMockMvcResultAssert<?> exchange();
}Usage Examples:
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;
@SpringJUnitWebConfig(WebConfig.class)
class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
void shouldReturnUserList() throws Exception {
mockMvc.perform(get("/users")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$").isArray())
.andExpect(jsonPath("$[0].name").value("John"))
.andDo(print());
}
@Test
void shouldCreateUser() throws Exception {
String userJson = """
{
"name": "Jane Doe",
"email": "jane@example.com"
}
""";
mockMvc.perform(post("/users")
.contentType(MediaType.APPLICATION_JSON)
.content(userJson))
.andExpect(status().isCreated())
.andExpect(header().exists("Location"))
.andExpect(jsonPath("$.id").exists())
.andExpect(jsonPath("$.name").value("Jane Doe"));
}
@Test
void shouldHandleValidationErrors() throws Exception {
String invalidUserJson = """
{
"name": "",
"email": "invalid-email"
}
""";
mockMvc.perform(post("/users")
.contentType(MediaType.APPLICATION_JSON)
.content(invalidUserJson))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.errors").isArray())
.andExpect(jsonPath("$.errors[?(@.field == 'name')]").exists())
.andExpect(jsonPath("$.errors[?(@.field == 'email')]").exists());
}
}
// Standalone setup example
@Test
void standaloneControllerTest() throws Exception {
UserController controller = new UserController(mockUserService);
MockMvc mockMvc = MockMvcBuilders.standaloneSetup(controller)
.setControllerAdvice(new GlobalExceptionHandler())
.addFilter(new CorsFilter())
.build();
mockMvc.perform(get("/users/1"))
.andExpect(status().isOk());
}
// AssertJ style testing
@Test
void assertJStyleTest() {
MockMvcTester tester = MockMvcTester.create(mockMvc);
tester.get("/users/{id}", 1)
.exchange()
.andExpect(status().isOk())
.andExpect(jsonPath("$.name").value("John"));
}/**
* Contract for building a MockHttpServletRequest.
*/
public interface RequestBuilder {
/**
* Build the request.
* @param servletContext the ServletContext to use
* @return the built MockHttpServletRequest
*/
MockHttpServletRequest buildRequest(ServletContext servletContext);
}
/**
* A contract for matching the result of an executed request.
*/
public interface ResultMatcher {
/**
* Assert the result of an executed request.
* @param result the result of the executed request
* @throws Exception if the assertion fails
*/
void match(MvcResult result) throws Exception;
}
/**
* A contract that can be used to apply actions to the result of an executed request.
*/
public interface ResultHandler {
/**
* Apply the action to the given result.
* @param result the result of the executed request
* @throws Exception if applying the action fails
*/
void handle(MvcResult result) throws Exception;
}
/**
* Provides access to the result of an executed request.
*/
public interface MvcResult {
/**
* Return the performed request.
* @return the request (never null)
*/
MockHttpServletRequest getRequest();
/**
* Return the resulting response.
* @return the response (never null)
*/
MockHttpServletResponse getResponse();
/**
* Return the executed handler.
* @return the handler (may be null)
*/
@Nullable
Object getHandler();
/**
* Return the HandlerInterceptor instances applied during request processing.
* @return the interceptor chain (may be null)
*/
@Nullable
HandlerInterceptor[] getInterceptors();
/**
* Return the ModelAndView prepared by the handler.
* @return the ModelAndView (may be null)
*/
@Nullable
ModelAndView getModelAndView();
/**
* Return any exception raised by a handler and successfully resolved through a HandlerExceptionResolver.
* @return the resolved exception (may be null)
*/
@Nullable
Exception getResolvedException();
/**
* Return the "output" flash attributes saved during request processing.
* @return the flash attributes (never null)
*/
FlashMap getFlashMap();
}
/**
* Contract for post-processing a MockHttpServletRequest.
*/
public interface RequestPostProcessor {
/**
* Post-process the given MockHttpServletRequest.
* @param request the request to post-process
* @return the processed request (may be the same instance or a new one)
*/
MockHttpServletRequest postProcessRequest(MockHttpServletRequest request);
}Client for testing web servers using a fluent API, supporting both mock and live server testing for reactive and traditional Spring MVC applications.
/**
* Client for testing web servers that uses WebClient internally to perform requests
* while also providing a fluent API to verify responses. Can connect to any server
* over HTTP, or to a WebFlux application via mock request and response objects.
*/
public interface WebTestClient {
/**
* Prepare an HTTP GET request.
* @return a spec for specifying the target URL
*/
RequestHeadersUriSpec<?> get();
/**
* Prepare an HTTP HEAD request.
* @return a spec for specifying the target URL
*/
RequestHeadersUriSpec<?> head();
/**
* Prepare an HTTP POST request.
* @return a spec for specifying the target URL
*/
RequestBodyUriSpec post();
/**
* Prepare an HTTP PUT request.
* @return a spec for specifying the target URL
*/
RequestBodyUriSpec put();
/**
* Prepare an HTTP PATCH request.
* @return a spec for specifying the target URL
*/
RequestBodyUriSpec patch();
/**
* Prepare an HTTP DELETE request.
* @return a spec for specifying the target URL
*/
RequestHeadersUriSpec<?> delete();
/**
* Prepare an HTTP OPTIONS request.
* @return a spec for specifying the target URL
*/
RequestHeadersUriSpec<?> options();
/**
* Prepare a request for the specified HttpMethod.
* @param method the HTTP method
* @return a spec for specifying the target URL
*/
RequestBodyUriSpec method(HttpMethod method);
/**
* Return a builder to mutate properties of this web test client.
* @return a builder for further configuration
*/
Builder mutate();
/**
* Mutate this WebTestClient, apply the given configurer, and build a new instance.
* @param configurer the configurer to apply
* @return a new WebTestClient instance
*/
WebTestClient mutateWith(WebTestClientConfigurer configurer);
/**
* Create a WebTestClient bound to the given controller.
* @param controllers one or more controllers to test
* @return a ControllerSpec for further configuration
*/
static ControllerSpec bindToController(Object... controllers);
/**
* Create a WebTestClient bound to the given RouterFunction.
* @param routerFunction the RouterFunction to test
* @return a RouterFunctionSpec for further configuration
*/
static RouterFunctionSpec bindToRouterFunction(RouterFunction<?> routerFunction);
/**
* Create a WebTestClient bound to the given ApplicationContext.
* @param applicationContext the context to load configuration from
* @return a MockServerSpec for further configuration
*/
static MockServerSpec<?> bindToApplicationContext(ApplicationContext applicationContext);
/**
* Create a WebTestClient bound to the given WebHandler.
* @param webHandler the WebHandler to test
* @return a MockServerSpec for further configuration
*/
static MockServerSpec<?> bindToWebHandler(WebHandler webHandler);
/**
* Create a WebTestClient for integration testing against a live server.
* @return a Builder for further configuration
*/
static Builder bindToServer();
/**
* Create a WebTestClient for integration testing with a specific connector.
* @param connector the ClientHttpConnector to use
* @return a Builder for further configuration
*/
static Builder bindToServer(ClientHttpConnector connector);
}
/**
* Contract for encapsulating customizations to WebTestClient.Builder.
*/
public interface WebTestClientConfigurer {
/**
* Invoked once only, immediately (i.e. before this method returns).
* @param builder the WebTestClient builder to customize
* @param httpHandlerBuilder the builder for the "mock server" HttpHandler
* @param connector the connector for "live" integration tests
*/
void afterConfigurerAdded(WebTestClient.Builder builder,
@Nullable WebHttpHandlerBuilder httpHandlerBuilder,
@Nullable ClientHttpConnector connector);
}
/**
* Contract that frameworks or applications can use to pre-package a set of
* customizations to WebTestClient.MockServerSpec and expose that as a shortcut.
*/
public interface MockServerConfigurer extends WebTestClientConfigurer {
/**
* Invoked immediately, i.e. before this method returns.
* @param serverSpec the MockServerSpec to customize
*/
default void afterConfigureAdded(WebTestClient.MockServerSpec<?> serverSpec) {
}
/**
* Invoked just before the mock server is created.
* @param builder the builder for the HttpHandler that will handle requests
*/
default void beforeServerCreated(WebHttpHandlerBuilder builder) {
}
}
/**
* Specification for creating a WebTestClient bound to MockMvc.
*/
public final class MockMvcWebTestClient {
/**
* Create a WebTestClient bound to the given controller.
* @param controllers one or more controllers to test
* @return a ControllerSpec for further configuration
*/
public static WebTestClient.ControllerSpec bindToController(Object... controllers);
/**
* Create a WebTestClient bound to the given RouterFunction.
* @param routerFunctions one or more RouterFunction instances
* @return a RouterFunctionSpec for further configuration
*/
public static WebTestClient.RouterFunctionSpec bindToRouterFunction(RouterFunction<?>... routerFunctions);
/**
* Create a WebTestClient bound to the given WebApplicationContext.
* @param context the WebApplicationContext to use
* @return a MockMvcServerSpec for further configuration
*/
public static MockMvcServerSpec<?> bindToApplicationContext(WebApplicationContext context);
/**
* Create a WebTestClient bound to the given MockMvc instance.
* @param mockMvc the MockMvc instance to bind to
* @return a Builder for further configuration
*/
public static WebTestClient.Builder bindTo(MockMvc mockMvc);
/**
* Return ResultActions to further verify the response.
* @param exchangeResult the result from WebTestClient
* @return ResultActions for MockMvc-style verification
*/
public static ResultActions resultActionsFor(ExchangeResult exchangeResult);
}Usage Examples:
// Controller testing
WebTestClient client = WebTestClient
.bindToController(new PersonController())
.build();
client.get().uri("/persons/1")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
.expectBody(Person.class)
.value(person -> {
assertEquals("John", person.getName());
assertEquals(30, person.getAge());
});
// Application context testing
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class IntegrationTest {
@Autowired
private TestRestTemplate restTemplate;
private WebTestClient webTestClient;
@BeforeEach
void setUp() {
webTestClient = WebTestClient
.bindToServer()
.baseUrl("http://localhost:" + port)
.build();
}
@Test
void testReactiveEndpoint() {
webTestClient.get().uri("/api/persons")
.exchange()
.expectStatus().isOk()
.expectBody()
.jsonPath("$[0].name").isEqualTo("John")
.jsonPath("$[0].age").isEqualTo(30);
}
}
// JSON content verification
webTestClient.post().uri("/persons")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(new Person("Jane", 25))
.exchange()
.expectStatus().isCreated()
.expectBody().json("""
{
"name": "Jane",
"age": 25,
"id": 2
}
""");
// Streaming response testing
webTestClient.get().uri("/persons/stream")
.accept(MediaType.APPLICATION_NDJSON)
.exchange()
.expectStatus().isOk()
.expectHeader().contentType(MediaType.APPLICATION_NDJSON)
.expectBodyList(Person.class)
.hasSize(10);Install with Tessl CLI
npx tessl i tessl/maven-org-springframework--spring-test