or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bean-override-framework.mdindex.mdjdbc-testing.mdjunit-integration.mdmock-objects.mdtestcontext-framework.mdtesting-annotations.mdweb-testing.md

web-testing.mddocs/

0

# Web Testing Support

1

2

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.

3

4

## Capabilities

5

6

### MockMvc

7

8

The main entry point for server-side Spring MVC testing, providing request execution and result assertion capabilities.

9

10

```java { .api }

11

/**

12

* Main entry point for server-side Spring MVC test support.

13

* Provides a fluent API to perform requests and verify results.

14

*/

15

public final class MockMvc {

16

17

/**

18

* Perform a request and return a type that allows chaining further actions,

19

* such as asserting expectations, on the result.

20

* @param requestBuilder used to prepare the request to execute

21

* @return an instance of ResultActions (never null)

22

* @throws Exception if an exception occurs during request execution

23

*/

24

public ResultActions perform(RequestBuilder requestBuilder) throws Exception;

25

}

26

27

/**

28

* Factory class for creating MockMvc instances.

29

*/

30

public final class MockMvcBuilders {

31

32

/**

33

* Build a MockMvc instance using the given WebApplicationContext.

34

* @param context the WebApplicationContext to use

35

* @return a MockMvcBuilder to further configure the MockMvc instance

36

*/

37

public static DefaultMockMvcBuilder webAppContextSetup(WebApplicationContext context);

38

39

/**

40

* Build a MockMvc instance by registering one or more @Controller instances

41

* and configuring Spring MVC infrastructure programmatically.

42

* @param controllers one or more @Controller instances to test

43

* @return a StandaloneMockMvcBuilder to further configure the MockMvc instance

44

*/

45

public static StandaloneMockMvcBuilder standaloneSetup(Object... controllers);

46

47

/**

48

* Build a MockMvc instance using the given RouterFunction.

49

* @param routerFunction the RouterFunction to use

50

* @return a MockMvcBuilder to further configure the MockMvc instance

51

*/

52

public static RouterFunctionMockMvcBuilder routerFunction(RouterFunction<?> routerFunction);

53

}

54

```

55

56

### Request Building

57

58

Factory and builder classes for creating HTTP requests in tests.

59

60

```java { .api }

61

/**

62

* Static factory methods for RequestBuilder instances that create various types of HTTP requests.

63

*/

64

public abstract class MockMvcRequestBuilders {

65

66

/**

67

* Create a MockHttpServletRequestBuilder for a GET request.

68

* @param urlTemplate a URL template; the resulting URL will be encoded

69

* @param uriVariables zero or more URI variables

70

* @return the request builder

71

*/

72

public static MockHttpServletRequestBuilder get(String urlTemplate, Object... uriVariables);

73

74

/**

75

* Create a MockHttpServletRequestBuilder for a POST request.

76

* @param urlTemplate a URL template; the resulting URL will be encoded

77

* @param uriVariables zero or more URI variables

78

* @return the request builder

79

*/

80

public static MockHttpServletRequestBuilder post(String urlTemplate, Object... uriVariables);

81

82

/**

83

* Create a MockHttpServletRequestBuilder for a PUT request.

84

* @param urlTemplate a URL template; the resulting URL will be encoded

85

* @param uriVariables zero or more URI variables

86

* @return the request builder

87

*/

88

public static MockHttpServletRequestBuilder put(String urlTemplate, Object... uriVariables);

89

90

/**

91

* Create a MockHttpServletRequestBuilder for a PATCH request.

92

* @param urlTemplate a URL template; the resulting URL will be encoded

93

* @param uriVariables zero or more URI variables

94

* @return the request builder

95

*/

96

public static MockHttpServletRequestBuilder patch(String urlTemplate, Object... uriVariables);

97

98

/**

99

* Create a MockHttpServletRequestBuilder for a DELETE request.

100

* @param urlTemplate a URL template; the resulting URL will be encoded

101

* @param uriVariables zero or more URI variables

102

* @return the request builder

103

*/

104

public static MockHttpServletRequestBuilder delete(String urlTemplate, Object... uriVariables);

105

106

/**

107

* Create a MockHttpServletRequestBuilder for a HEAD request.

108

* @param urlTemplate a URL template; the resulting URL will be encoded

109

* @param uriVariables zero or more URI variables

110

* @return the request builder

111

*/

112

public static MockHttpServletRequestBuilder head(String urlTemplate, Object... uriVariables);

113

114

/**

115

* Create a MockHttpServletRequestBuilder for an OPTIONS request.

116

* @param urlTemplate a URL template; the resulting URL will be encoded

117

* @param uriVariables zero or more URI variables

118

* @return the request builder

119

*/

120

public static MockHttpServletRequestBuilder options(String urlTemplate, Object... uriVariables);

121

122

/**

123

* Create a MockMultipartHttpServletRequestBuilder for a multipart request.

124

* @param urlTemplate a URL template; the resulting URL will be encoded

125

* @param uriVariables zero or more URI variables

126

* @return the request builder

127

*/

128

public static MockMultipartHttpServletRequestBuilder multipart(String urlTemplate, Object... uriVariables);

129

130

/**

131

* Create a RequestBuilder for an async dispatch from the MvcResult of the request.

132

* @param mvcResult the result from the request that initiated async processing

133

* @return the request builder for the async dispatch

134

*/

135

public static RequestBuilder asyncDispatch(MvcResult mvcResult);

136

}

137

138

/**

139

* Default builder for MockHttpServletRequest instances.

140

*/

141

public class MockHttpServletRequestBuilder implements ConfigurableSmartRequestBuilder<MockHttpServletRequestBuilder> {

142

143

/**

144

* Add a request parameter to the MockHttpServletRequest.

145

* @param name the parameter name

146

* @param values one or more values

147

* @return this request builder

148

*/

149

public MockHttpServletRequestBuilder param(String name, String... values);

150

151

/**

152

* Add multiple request parameters and values.

153

* @param params the parameters to add

154

* @return this request builder

155

*/

156

public MockHttpServletRequestBuilder params(MultiValueMap<String, String> params);

157

158

/**

159

* Add a header to the request.

160

* @param name the header name

161

* @param values one or more header values

162

* @return this request builder

163

*/

164

public MockHttpServletRequestBuilder header(String name, Object... values);

165

166

/**

167

* Add all headers from the given HttpHeaders object.

168

* @param httpHeaders the HttpHeaders object

169

* @return this request builder

170

*/

171

public MockHttpServletRequestBuilder headers(HttpHeaders httpHeaders);

172

173

/**

174

* Set the content type of the request.

175

* @param contentType the content type

176

* @return this request builder

177

*/

178

public MockHttpServletRequestBuilder contentType(MediaType contentType);

179

180

/**

181

* Set the Accept header of the request.

182

* @param mediaTypes one or more media types

183

* @return this request builder

184

*/

185

public MockHttpServletRequestBuilder accept(MediaType... mediaTypes);

186

187

/**

188

* Set the content of the request body.

189

* @param content the body content

190

* @return this request builder

191

*/

192

public MockHttpServletRequestBuilder content(String content);

193

194

/**

195

* Set the content of the request body as a byte array.

196

* @param content the body content

197

* @return this request builder

198

*/

199

public MockHttpServletRequestBuilder content(byte[] content);

200

201

/**

202

* Add a cookie to the request.

203

* @param cookies one or more cookies

204

* @return this request builder

205

*/

206

public MockHttpServletRequestBuilder cookie(Cookie... cookies);

207

208

/**

209

* Set the locale of the request.

210

* @param locale the locale

211

* @return this request builder

212

*/

213

public MockHttpServletRequestBuilder locale(Locale locale);

214

215

/**

216

* Set the character encoding of the request.

217

* @param encoding the character encoding

218

* @return this request builder

219

*/

220

public MockHttpServletRequestBuilder characterEncoding(String encoding);

221

222

/**

223

* Apply the given RequestPostProcessor.

224

* @param postProcessor the post processor to apply

225

* @return this request builder

226

*/

227

public MockHttpServletRequestBuilder with(RequestPostProcessor postProcessor);

228

}

229

```

230

231

### Result Actions and Matchers

232

233

Interfaces and factory classes for asserting the results of MockMvc requests.

234

235

```java { .api }

236

/**

237

* Allows applying actions, such as expectations, on the result of an executed request.

238

*/

239

public interface ResultActions {

240

241

/**

242

* Perform an expectation.

243

* @param matcher the expectation

244

* @return this ResultActions instance for method chaining

245

* @throws Exception if the expectation fails

246

*/

247

ResultActions andExpect(ResultMatcher matcher) throws Exception;

248

249

/**

250

* Perform multiple expectations.

251

* @param matchers the expectations

252

* @return this ResultActions instance for method chaining

253

* @throws Exception if any expectation fails

254

*/

255

ResultActions andExpectAll(ResultMatcher... matchers) throws Exception;

256

257

/**

258

* Perform a general action.

259

* @param handler the handler to execute

260

* @return this ResultActions instance for method chaining

261

* @throws Exception if the action fails

262

*/

263

ResultActions andDo(ResultHandler handler) throws Exception;

264

265

/**

266

* Return the result of the executed request for direct access to the results.

267

* @return the MvcResult

268

*/

269

MvcResult andReturn();

270

}

271

272

/**

273

* Factory for assertions on the result of a request executed through MockMvc.

274

*/

275

public abstract class MockMvcResultMatchers {

276

277

/**

278

* Access to request-related assertions.

279

* @return the RequestResultMatchers instance

280

*/

281

public static RequestResultMatchers request();

282

283

/**

284

* Access to response status assertions.

285

* @return the StatusResultMatchers instance

286

*/

287

public static StatusResultMatchers status();

288

289

/**

290

* Access to response header assertions.

291

* @return the HeaderResultMatchers instance

292

*/

293

public static HeaderResultMatchers header();

294

295

/**

296

* Access to response content assertions.

297

* @return the ContentResultMatchers instance

298

*/

299

public static ContentResultMatchers content();

300

301

/**

302

* Access to response body JSON path assertions.

303

* @param expression the JSON path expression

304

* @param args arguments to parameterize the JSON path expression with

305

* @return the JsonPathResultMatchers instance

306

*/

307

public static JsonPathResultMatchers jsonPath(String expression, Object... args);

308

309

/**

310

* Access to response body XPath assertions.

311

* @param expression the XPath expression

312

* @param args arguments to parameterize the XPath expression with

313

* @return the XpathResultMatchers instance

314

*/

315

public static XpathResultMatchers xpath(String expression, Object... args);

316

317

/**

318

* Access to model-related assertions.

319

* @return the ModelResultMatchers instance

320

*/

321

public static ModelResultMatchers model();

322

323

/**

324

* Access to view-related assertions.

325

* @return the ViewResultMatchers instance

326

*/

327

public static ViewResultMatchers view();

328

329

/**

330

* Access to flash attribute assertions.

331

* @return the FlashAttributeResultMatchers instance

332

*/

333

public static FlashAttributeResultMatchers flash();

334

335

/**

336

* Access to redirect URL assertions.

337

* @param expectedUrl the expected redirect URL

338

* @return the ResultMatcher instance

339

*/

340

public static ResultMatcher redirectedUrl(String expectedUrl);

341

342

/**

343

* Access to forwarded URL assertions.

344

* @param expectedUrl the expected forward URL

345

* @return the ResultMatcher instance

346

*/

347

public static ResultMatcher forwardedUrl(String expectedUrl);

348

349

/**

350

* Access to cookie-related assertions.

351

* @return the CookieResultMatchers instance

352

*/

353

public static CookieResultMatchers cookie();

354

}

355

356

/**

357

* Factory for response status assertions.

358

*/

359

public class StatusResultMatchers {

360

361

/**

362

* Assert the response status code is equal to the given status.

363

* @param status the expected status

364

* @return the ResultMatcher

365

*/

366

public ResultMatcher is(HttpStatus status);

367

368

/**

369

* Assert the response status code is equal to the given integer value.

370

* @param status the expected status code

371

* @return the ResultMatcher

372

*/

373

public ResultMatcher is(int status);

374

375

/**

376

* Assert the response status code is 200 (OK).

377

* @return the ResultMatcher

378

*/

379

public ResultMatcher isOk();

380

381

/**

382

* Assert the response status code is 201 (Created).

383

* @return the ResultMatcher

384

*/

385

public ResultMatcher isCreated();

386

387

/**

388

* Assert the response status code is 202 (Accepted).

389

* @return the ResultMatcher

390

*/

391

public ResultMatcher isAccepted();

392

393

/**

394

* Assert the response status code is 204 (No Content).

395

* @return the ResultMatcher

396

*/

397

public ResultMatcher isNoContent();

398

399

/**

400

* Assert the response status code is 400 (Bad Request).

401

* @return the ResultMatcher

402

*/

403

public ResultMatcher isBadRequest();

404

405

/**

406

* Assert the response status code is 401 (Unauthorized).

407

* @return the ResultMatcher

408

*/

409

public ResultMatcher isUnauthorized();

410

411

/**

412

* Assert the response status code is 403 (Forbidden).

413

* @return the ResultMatcher

414

*/

415

public ResultMatcher isForbidden();

416

417

/**

418

* Assert the response status code is 404 (Not Found).

419

* @return the ResultMatcher

420

*/

421

public ResultMatcher isNotFound();

422

423

/**

424

* Assert the response status code is 500 (Internal Server Error).

425

* @return the ResultMatcher

426

*/

427

public ResultMatcher isInternalServerError();

428

}

429

430

/**

431

* Factory for response content assertions.

432

*/

433

public class ContentResultMatchers {

434

435

/**

436

* Assert the response content type using a MediaType.

437

* @param contentType the expected content type

438

* @return the ResultMatcher

439

*/

440

public ResultMatcher contentType(MediaType contentType);

441

442

/**

443

* Assert the response content type as a String.

444

* @param contentType the expected content type

445

* @return the ResultMatcher

446

*/

447

public ResultMatcher contentType(String contentType);

448

449

/**

450

* Assert the response content encoding.

451

* @param characterEncoding the expected character encoding

452

* @return the ResultMatcher

453

*/

454

public ResultMatcher encoding(String characterEncoding);

455

456

/**

457

* Assert the response content as a String.

458

* @param expectedContent the expected content

459

* @return the ResultMatcher

460

*/

461

public ResultMatcher string(String expectedContent);

462

463

/**

464

* Assert the response content matches the given Hamcrest matcher.

465

* @param matcher the Hamcrest matcher

466

* @return the ResultMatcher

467

*/

468

public ResultMatcher string(Matcher<? super String> matcher);

469

470

/**

471

* Assert the response content as a byte array.

472

* @param expectedContent the expected content

473

* @return the ResultMatcher

474

*/

475

public ResultMatcher bytes(byte[] expectedContent);

476

477

/**

478

* Assert the response content as JSON.

479

* @param jsonContent the expected JSON content

480

* @return the ResultMatcher

481

*/

482

public ResultMatcher json(String jsonContent);

483

484

/**

485

* Assert the response content as JSON with strict comparison.

486

* @param jsonContent the expected JSON content

487

* @param strict whether to use strict comparison

488

* @return the ResultMatcher

489

*/

490

public ResultMatcher json(String jsonContent, boolean strict);

491

492

/**

493

* Assert the response content as XML.

494

* @param xmlContent the expected XML content

495

* @return the ResultMatcher

496

*/

497

public ResultMatcher xml(String xmlContent);

498

}

499

```

500

501

### Result Handlers

502

503

Factory for actions to perform on MockMvc results.

504

505

```java { .api }

506

/**

507

* Static factory methods for ResultHandler instances.

508

*/

509

public abstract class MockMvcResultHandlers {

510

511

/**

512

* Print the request and response details to System.out.

513

* @return the ResultHandler instance

514

*/

515

public static ResultHandler print();

516

517

/**

518

* Print the request and response details to the given OutputStream.

519

* @param stream the target stream

520

* @return the ResultHandler instance

521

*/

522

public static ResultHandler print(OutputStream stream);

523

524

/**

525

* Print the request and response details to the given Writer.

526

* @param writer the target writer

527

* @return the ResultHandler instance

528

*/

529

public static ResultHandler print(Writer writer);

530

531

/**

532

* Log the request and response details at DEBUG level using the given logger.

533

* @return the ResultHandler instance

534

*/

535

public static ResultHandler log();

536

}

537

```

538

539

### AssertJ Integration

540

541

Modern AssertJ-style fluent assertions for MockMvc testing.

542

543

```java { .api }

544

/**

545

* AssertJ-style assertions for MockMvc.

546

* Provides fluent API for testing Spring MVC applications.

547

*/

548

public class MockMvcTester {

549

550

/**

551

* Create a MockMvcTester instance from the given MockMvc.

552

* @param mockMvc the MockMvc instance

553

* @return the MockMvcTester instance

554

*/

555

public static MockMvcTester create(MockMvc mockMvc);

556

557

/**

558

* Perform a GET request.

559

* @param uriTemplate the URI template

560

* @param uriVariables URI variables

561

* @return the MockMvcRequestSpec for further configuration

562

*/

563

public MockMvcRequestSpec get(String uriTemplate, Object... uriVariables);

564

565

/**

566

* Perform a POST request.

567

* @param uriTemplate the URI template

568

* @param uriVariables URI variables

569

* @return the MockMvcRequestSpec for further configuration

570

*/

571

public MockMvcRequestSpec post(String uriTemplate, Object... uriVariables);

572

573

/**

574

* Perform a PUT request.

575

* @param uriTemplate the URI template

576

* @param uriVariables URI variables

577

* @return the MockMvcRequestSpec for further configuration

578

*/

579

public MockMvcRequestSpec put(String uriTemplate, Object... uriVariables);

580

581

/**

582

* Perform a PATCH request.

583

* @param uriTemplate the URI template

584

* @param uriVariables URI variables

585

* @return the MockMvcRequestSpec for further configuration

586

*/

587

public MockMvcRequestSpec patch(String uriTemplate, Object... uriVariables);

588

589

/**

590

* Perform a DELETE request.

591

* @param uriTemplate the URI template

592

* @param uriVariables URI variables

593

* @return the MockMvcRequestSpec for further configuration

594

*/

595

public MockMvcRequestSpec delete(String uriTemplate, Object... uriVariables);

596

}

597

598

/**

599

* AssertJ-style request specification for MockMvc testing.

600

*/

601

public class MockMvcRequestSpec {

602

603

/**

604

* Add a request parameter.

605

* @param name the parameter name

606

* @param values one or more parameter values

607

* @return this request spec

608

*/

609

public MockMvcRequestSpec param(String name, String... values);

610

611

/**

612

* Add a request header.

613

* @param name the header name

614

* @param values one or more header values

615

* @return this request spec

616

*/

617

public MockMvcRequestSpec header(String name, Object... values);

618

619

/**

620

* Set the content type.

621

* @param contentType the content type

622

* @return this request spec

623

*/

624

public MockMvcRequestSpec contentType(MediaType contentType);

625

626

/**

627

* Set the request content.

628

* @param content the content

629

* @return this request spec

630

*/

631

public MockMvcRequestSpec content(String content);

632

633

/**

634

* Execute the request and return assertions.

635

* @return the AbstractMockMvcResultAssert for assertions

636

*/

637

public AbstractMockMvcResultAssert<?> exchange();

638

}

639

```

640

641

**Usage Examples:**

642

643

```java

644

import org.springframework.test.web.servlet.MockMvc;

645

import org.springframework.test.web.servlet.setup.MockMvcBuilders;

646

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;

647

import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

648

import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;

649

650

@SpringJUnitWebConfig(WebConfig.class)

651

class UserControllerTest {

652

653

@Autowired

654

private MockMvc mockMvc;

655

656

@Test

657

void shouldReturnUserList() throws Exception {

658

mockMvc.perform(get("/users")

659

.accept(MediaType.APPLICATION_JSON))

660

.andExpect(status().isOk())

661

.andExpect(content().contentType(MediaType.APPLICATION_JSON))

662

.andExpect(jsonPath("$").isArray())

663

.andExpect(jsonPath("$[0].name").value("John"))

664

.andDo(print());

665

}

666

667

@Test

668

void shouldCreateUser() throws Exception {

669

String userJson = """

670

{

671

"name": "Jane Doe",

672

"email": "jane@example.com"

673

}

674

""";

675

676

mockMvc.perform(post("/users")

677

.contentType(MediaType.APPLICATION_JSON)

678

.content(userJson))

679

.andExpect(status().isCreated())

680

.andExpect(header().exists("Location"))

681

.andExpect(jsonPath("$.id").exists())

682

.andExpect(jsonPath("$.name").value("Jane Doe"));

683

}

684

685

@Test

686

void shouldHandleValidationErrors() throws Exception {

687

String invalidUserJson = """

688

{

689

"name": "",

690

"email": "invalid-email"

691

}

692

""";

693

694

mockMvc.perform(post("/users")

695

.contentType(MediaType.APPLICATION_JSON)

696

.content(invalidUserJson))

697

.andExpect(status().isBadRequest())

698

.andExpect(jsonPath("$.errors").isArray())

699

.andExpect(jsonPath("$.errors[?(@.field == 'name')]").exists())

700

.andExpect(jsonPath("$.errors[?(@.field == 'email')]").exists());

701

}

702

}

703

704

// Standalone setup example

705

@Test

706

void standaloneControllerTest() throws Exception {

707

UserController controller = new UserController(mockUserService);

708

MockMvc mockMvc = MockMvcBuilders.standaloneSetup(controller)

709

.setControllerAdvice(new GlobalExceptionHandler())

710

.addFilter(new CorsFilter())

711

.build();

712

713

mockMvc.perform(get("/users/1"))

714

.andExpect(status().isOk());

715

}

716

717

// AssertJ style testing

718

@Test

719

void assertJStyleTest() {

720

MockMvcTester tester = MockMvcTester.create(mockMvc);

721

722

tester.get("/users/{id}", 1)

723

.exchange()

724

.andExpect(status().isOk())

725

.andExpect(jsonPath("$.name").value("John"));

726

}

727

```

728

729

## Types

730

731

```java { .api }

732

/**

733

* Contract for building a MockHttpServletRequest.

734

*/

735

public interface RequestBuilder {

736

737

/**

738

* Build the request.

739

* @param servletContext the ServletContext to use

740

* @return the built MockHttpServletRequest

741

*/

742

MockHttpServletRequest buildRequest(ServletContext servletContext);

743

}

744

745

/**

746

* A contract for matching the result of an executed request.

747

*/

748

public interface ResultMatcher {

749

750

/**

751

* Assert the result of an executed request.

752

* @param result the result of the executed request

753

* @throws Exception if the assertion fails

754

*/

755

void match(MvcResult result) throws Exception;

756

}

757

758

/**

759

* A contract that can be used to apply actions to the result of an executed request.

760

*/

761

public interface ResultHandler {

762

763

/**

764

* Apply the action to the given result.

765

* @param result the result of the executed request

766

* @throws Exception if applying the action fails

767

*/

768

void handle(MvcResult result) throws Exception;

769

}

770

771

/**

772

* Provides access to the result of an executed request.

773

*/

774

public interface MvcResult {

775

776

/**

777

* Return the performed request.

778

* @return the request (never null)

779

*/

780

MockHttpServletRequest getRequest();

781

782

/**

783

* Return the resulting response.

784

* @return the response (never null)

785

*/

786

MockHttpServletResponse getResponse();

787

788

/**

789

* Return the executed handler.

790

* @return the handler (may be null)

791

*/

792

@Nullable

793

Object getHandler();

794

795

/**

796

* Return the HandlerInterceptor instances applied during request processing.

797

* @return the interceptor chain (may be null)

798

*/

799

@Nullable

800

HandlerInterceptor[] getInterceptors();

801

802

/**

803

* Return the ModelAndView prepared by the handler.

804

* @return the ModelAndView (may be null)

805

*/

806

@Nullable

807

ModelAndView getModelAndView();

808

809

/**

810

* Return any exception raised by a handler and successfully resolved through a HandlerExceptionResolver.

811

* @return the resolved exception (may be null)

812

*/

813

@Nullable

814

Exception getResolvedException();

815

816

/**

817

* Return the "output" flash attributes saved during request processing.

818

* @return the flash attributes (never null)

819

*/

820

FlashMap getFlashMap();

821

}

822

823

/**

824

* Contract for post-processing a MockHttpServletRequest.

825

*/

826

public interface RequestPostProcessor {

827

828

/**

829

* Post-process the given MockHttpServletRequest.

830

* @param request the request to post-process

831

* @return the processed request (may be the same instance or a new one)

832

*/

833

MockHttpServletRequest postProcessRequest(MockHttpServletRequest request);

834

}

835

```

836

837

### WebTestClient

838

839

Client for testing web servers using a fluent API, supporting both mock and live server testing for reactive and traditional Spring MVC applications.

840

841

```java { .api }

842

/**

843

* Client for testing web servers that uses WebClient internally to perform requests

844

* while also providing a fluent API to verify responses. Can connect to any server

845

* over HTTP, or to a WebFlux application via mock request and response objects.

846

*/

847

public interface WebTestClient {

848

849

/**

850

* Prepare an HTTP GET request.

851

* @return a spec for specifying the target URL

852

*/

853

RequestHeadersUriSpec<?> get();

854

855

/**

856

* Prepare an HTTP HEAD request.

857

* @return a spec for specifying the target URL

858

*/

859

RequestHeadersUriSpec<?> head();

860

861

/**

862

* Prepare an HTTP POST request.

863

* @return a spec for specifying the target URL

864

*/

865

RequestBodyUriSpec post();

866

867

/**

868

* Prepare an HTTP PUT request.

869

* @return a spec for specifying the target URL

870

*/

871

RequestBodyUriSpec put();

872

873

/**

874

* Prepare an HTTP PATCH request.

875

* @return a spec for specifying the target URL

876

*/

877

RequestBodyUriSpec patch();

878

879

/**

880

* Prepare an HTTP DELETE request.

881

* @return a spec for specifying the target URL

882

*/

883

RequestHeadersUriSpec<?> delete();

884

885

/**

886

* Prepare an HTTP OPTIONS request.

887

* @return a spec for specifying the target URL

888

*/

889

RequestHeadersUriSpec<?> options();

890

891

/**

892

* Prepare a request for the specified HttpMethod.

893

* @param method the HTTP method

894

* @return a spec for specifying the target URL

895

*/

896

RequestBodyUriSpec method(HttpMethod method);

897

898

/**

899

* Return a builder to mutate properties of this web test client.

900

* @return a builder for further configuration

901

*/

902

Builder mutate();

903

904

/**

905

* Mutate this WebTestClient, apply the given configurer, and build a new instance.

906

* @param configurer the configurer to apply

907

* @return a new WebTestClient instance

908

*/

909

WebTestClient mutateWith(WebTestClientConfigurer configurer);

910

911

/**

912

* Create a WebTestClient bound to the given controller.

913

* @param controllers one or more controllers to test

914

* @return a ControllerSpec for further configuration

915

*/

916

static ControllerSpec bindToController(Object... controllers);

917

918

/**

919

* Create a WebTestClient bound to the given RouterFunction.

920

* @param routerFunction the RouterFunction to test

921

* @return a RouterFunctionSpec for further configuration

922

*/

923

static RouterFunctionSpec bindToRouterFunction(RouterFunction<?> routerFunction);

924

925

/**

926

* Create a WebTestClient bound to the given ApplicationContext.

927

* @param applicationContext the context to load configuration from

928

* @return a MockServerSpec for further configuration

929

*/

930

static MockServerSpec<?> bindToApplicationContext(ApplicationContext applicationContext);

931

932

/**

933

* Create a WebTestClient bound to the given WebHandler.

934

* @param webHandler the WebHandler to test

935

* @return a MockServerSpec for further configuration

936

*/

937

static MockServerSpec<?> bindToWebHandler(WebHandler webHandler);

938

939

/**

940

* Create a WebTestClient for integration testing against a live server.

941

* @return a Builder for further configuration

942

*/

943

static Builder bindToServer();

944

945

/**

946

* Create a WebTestClient for integration testing with a specific connector.

947

* @param connector the ClientHttpConnector to use

948

* @return a Builder for further configuration

949

*/

950

static Builder bindToServer(ClientHttpConnector connector);

951

}

952

953

/**

954

* Contract for encapsulating customizations to WebTestClient.Builder.

955

*/

956

public interface WebTestClientConfigurer {

957

958

/**

959

* Invoked once only, immediately (i.e. before this method returns).

960

* @param builder the WebTestClient builder to customize

961

* @param httpHandlerBuilder the builder for the "mock server" HttpHandler

962

* @param connector the connector for "live" integration tests

963

*/

964

void afterConfigurerAdded(WebTestClient.Builder builder,

965

@Nullable WebHttpHandlerBuilder httpHandlerBuilder,

966

@Nullable ClientHttpConnector connector);

967

}

968

969

/**

970

* Contract that frameworks or applications can use to pre-package a set of

971

* customizations to WebTestClient.MockServerSpec and expose that as a shortcut.

972

*/

973

public interface MockServerConfigurer extends WebTestClientConfigurer {

974

975

/**

976

* Invoked immediately, i.e. before this method returns.

977

* @param serverSpec the MockServerSpec to customize

978

*/

979

default void afterConfigureAdded(WebTestClient.MockServerSpec<?> serverSpec) {

980

}

981

982

/**

983

* Invoked just before the mock server is created.

984

* @param builder the builder for the HttpHandler that will handle requests

985

*/

986

default void beforeServerCreated(WebHttpHandlerBuilder builder) {

987

}

988

}

989

990

/**

991

* Specification for creating a WebTestClient bound to MockMvc.

992

*/

993

public final class MockMvcWebTestClient {

994

995

/**

996

* Create a WebTestClient bound to the given controller.

997

* @param controllers one or more controllers to test

998

* @return a ControllerSpec for further configuration

999

*/

1000

public static WebTestClient.ControllerSpec bindToController(Object... controllers);

1001

1002

/**

1003

* Create a WebTestClient bound to the given RouterFunction.

1004

* @param routerFunctions one or more RouterFunction instances

1005

* @return a RouterFunctionSpec for further configuration

1006

*/

1007

public static WebTestClient.RouterFunctionSpec bindToRouterFunction(RouterFunction<?>... routerFunctions);

1008

1009

/**

1010

* Create a WebTestClient bound to the given WebApplicationContext.

1011

* @param context the WebApplicationContext to use

1012

* @return a MockMvcServerSpec for further configuration

1013

*/

1014

public static MockMvcServerSpec<?> bindToApplicationContext(WebApplicationContext context);

1015

1016

/**

1017

* Create a WebTestClient bound to the given MockMvc instance.

1018

* @param mockMvc the MockMvc instance to bind to

1019

* @return a Builder for further configuration

1020

*/

1021

public static WebTestClient.Builder bindTo(MockMvc mockMvc);

1022

1023

/**

1024

* Return ResultActions to further verify the response.

1025

* @param exchangeResult the result from WebTestClient

1026

* @return ResultActions for MockMvc-style verification

1027

*/

1028

public static ResultActions resultActionsFor(ExchangeResult exchangeResult);

1029

}

1030

```

1031

1032

**Usage Examples:**

1033

1034

```java

1035

// Controller testing

1036

WebTestClient client = WebTestClient

1037

.bindToController(new PersonController())

1038

.build();

1039

1040

client.get().uri("/persons/1")

1041

.accept(MediaType.APPLICATION_JSON)

1042

.exchange()

1043

.expectStatus().isOk()

1044

.expectBody(Person.class)

1045

.value(person -> {

1046

assertEquals("John", person.getName());

1047

assertEquals(30, person.getAge());

1048

});

1049

1050

// Application context testing

1051

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)

1052

class IntegrationTest {

1053

1054

@Autowired

1055

private TestRestTemplate restTemplate;

1056

1057

private WebTestClient webTestClient;

1058

1059

@BeforeEach

1060

void setUp() {

1061

webTestClient = WebTestClient

1062

.bindToServer()

1063

.baseUrl("http://localhost:" + port)

1064

.build();

1065

}

1066

1067

@Test

1068

void testReactiveEndpoint() {

1069

webTestClient.get().uri("/api/persons")

1070

.exchange()

1071

.expectStatus().isOk()

1072

.expectBody()

1073

.jsonPath("$[0].name").isEqualTo("John")

1074

.jsonPath("$[0].age").isEqualTo(30);

1075

}

1076

}

1077

1078

// JSON content verification

1079

webTestClient.post().uri("/persons")

1080

.contentType(MediaType.APPLICATION_JSON)

1081

.bodyValue(new Person("Jane", 25))

1082

.exchange()

1083

.expectStatus().isCreated()

1084

.expectBody().json("""

1085

{

1086

"name": "Jane",

1087

"age": 25,

1088

"id": 2

1089

}

1090

""");

1091

1092

// Streaming response testing

1093

webTestClient.get().uri("/persons/stream")

1094

.accept(MediaType.APPLICATION_NDJSON)

1095

.exchange()

1096

.expectStatus().isOk()

1097

.expectHeader().contentType(MediaType.APPLICATION_NDJSON)

1098

.expectBodyList(Person.class)

1099

.hasSize(10);

1100

```