or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdcontrollers.mdembedded-server.mderror-handling.mdhttp-clients.mdindex.mdjson-processing.mdstatic-resources.mdtesting.md

testing.mddocs/

0

# Web Testing

1

2

Spring Boot provides comprehensive testing support for web applications with dedicated annotations and testing utilities for controllers, web layers, and full integration testing.

3

4

## Capabilities

5

6

### @WebMvcTest Integration

7

8

Test Spring MVC controllers with focused test slicing that loads only web layer components.

9

10

```java { .api }

11

/**

12

* Web MVC test annotation for controller testing

13

*/

14

@WebMvcTest(UserController.class)

15

@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)

16

class UserControllerTest {

17

18

@Autowired

19

private MockMvc mockMvc;

20

21

@MockBean

22

private UserService userService;

23

24

@Test

25

void shouldGetUser() throws Exception {

26

// Test implementation

27

}

28

}

29

30

/**

31

* Web MVC test for all controllers

32

*/

33

@WebMvcTest

34

class AllControllersTest {

35

@Autowired

36

private MockMvc mockMvc;

37

}

38

```

39

40

**Usage Examples:**

41

42

```java

43

@WebMvcTest(ProductController.class)

44

class ProductControllerTest {

45

46

@Autowired

47

private MockMvc mockMvc;

48

49

@MockBean

50

private ProductService productService;

51

52

@Autowired

53

private ObjectMapper objectMapper;

54

55

@Test

56

void shouldCreateProduct() throws Exception {

57

Product product = new Product("Test Product", 29.99);

58

Product savedProduct = new Product(1L, "Test Product", 29.99);

59

60

when(productService.save(any(Product.class))).thenReturn(savedProduct);

61

62

mockMvc.perform(post("/api/products")

63

.contentType(MediaType.APPLICATION_JSON)

64

.content(objectMapper.writeValueAsString(product)))

65

.andExpect(status().isCreated())

66

.andExpect(jsonPath("$.id").value(1))

67

.andExpect(jsonPath("$.name").value("Test Product"))

68

.andExpect(jsonPath("$.price").value(29.99));

69

}

70

71

@Test

72

void shouldGetProduct() throws Exception {

73

Product product = new Product(1L, "Test Product", 29.99);

74

when(productService.findById(1L)).thenReturn(product);

75

76

mockMvc.perform(get("/api/products/1"))

77

.andExpect(status().isOk())

78

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

79

.andExpect(jsonPath("$.name").value("Test Product"));

80

}

81

82

@Test

83

void shouldReturnNotFoundForNonExistentProduct() throws Exception {

84

when(productService.findById(999L)).thenThrow(new ProductNotFoundException());

85

86

mockMvc.perform(get("/api/products/999"))

87

.andExpect(status().isNotFound());

88

}

89

}

90

```

91

92

### MockMvc Testing

93

94

Comprehensive MockMvc API for testing web layer interactions.

95

96

```java { .api }

97

/**

98

* MockMvc request builders and matchers

99

*/

100

public class MockMvcRequestBuilders {

101

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

102

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

103

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

104

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

105

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

106

}

107

108

/**

109

* Request customization

110

*/

111

public interface MockHttpServletRequestBuilder {

112

MockHttpServletRequestBuilder contentType(MediaType mediaType);

113

MockHttpServletRequestBuilder content(String content);

114

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

115

MockHttpServletRequestBuilder headers(HttpHeaders httpHeaders);

116

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

117

MockHttpServletRequestBuilder cookie(Cookie... cookies);

118

MockHttpServletRequestBuilder sessionAttr(String name, Object value);

119

MockHttpServletRequestBuilder principal(Principal principal);

120

}

121

122

/**

123

* Response verification

124

*/

125

public class MockMvcResultMatchers {

126

public static StatusResultMatchers status();

127

public static ContentResultMatchers content();

128

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

129

public static HeaderResultMatchers header();

130

public static ModelResultMatchers model();

131

public static ViewResultMatchers view();

132

public static RedirectResultMatchers redirectedUrl(String expectedUrl);

133

}

134

```

135

136

**Usage Examples:**

137

138

```java

139

@Test

140

void shouldHandleFormSubmission() throws Exception {

141

mockMvc.perform(post("/users")

142

.param("name", "John Doe")

143

.param("email", "john@example.com")

144

.contentType(MediaType.APPLICATION_FORM_URLENCODED))

145

.andExpect(status().is3xxRedirection())

146

.andExpect(redirectedUrl("/users/success"));

147

}

148

149

@Test

150

void shouldHandleFileUpload() throws Exception {

151

MockMultipartFile file = new MockMultipartFile(

152

"file", "test.txt", "text/plain", "Hello, World!".getBytes());

153

154

mockMvc.perform(multipart("/api/upload")

155

.file(file)

156

.param("description", "Test file"))

157

.andExpect(status().isOk())

158

.andExpect(content().string(containsString("File uploaded")));

159

}

160

161

@Test

162

void shouldValidateRequestBody() throws Exception {

163

Product invalidProduct = new Product("", -10.0); // Invalid data

164

165

mockMvc.perform(post("/api/products")

166

.contentType(MediaType.APPLICATION_JSON)

167

.content(objectMapper.writeValueAsString(invalidProduct)))

168

.andExpect(status().isBadRequest())

169

.andExpect(jsonPath("$.name").value("Name is required"))

170

.andExpect(jsonPath("$.price").value("Price must be positive"));

171

}

172

```

173

174

### Integration Testing

175

176

Full application context testing with @SpringBootTest and TestRestTemplate.

177

178

```java { .api }

179

/**

180

* Full integration test with embedded server

181

*/

182

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)

183

class UserIntegrationTest {

184

185

@Autowired

186

private TestRestTemplate restTemplate;

187

188

@LocalServerPort

189

private int port;

190

191

@Test

192

void shouldCreateAndRetrieveUser() {

193

// Integration test implementation

194

}

195

}

196

197

/**

198

* Integration test with mock web environment

199

*/

200

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)

201

@AutoConfigureTestDatabase

202

class UserRepositoryIntegrationTest {

203

204

@Autowired

205

private MockMvc mockMvc;

206

207

@Autowired

208

private UserRepository userRepository;

209

}

210

```

211

212

**Usage Examples:**

213

214

```java

215

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)

216

@TestPropertySource(locations = "classpath:application-test.properties")

217

class ProductIntegrationTest {

218

219

@Autowired

220

private TestRestTemplate restTemplate;

221

222

@Autowired

223

private ProductRepository productRepository;

224

225

@LocalServerPort

226

private int port;

227

228

@Test

229

void shouldCreateProductThroughApi() {

230

Product product = new Product("Integration Test Product", 39.99);

231

232

ResponseEntity<Product> response = restTemplate.postForEntity(

233

"/api/products", product, Product.class);

234

235

assertThat(response.getStatusCode()).isEqualTo(HttpStatus.CREATED);

236

assertThat(response.getBody().getId()).isNotNull();

237

assertThat(response.getBody().getName()).isEqualTo("Integration Test Product");

238

239

// Verify in database

240

Optional<Product> savedProduct = productRepository.findById(response.getBody().getId());

241

assertThat(savedProduct).isPresent();

242

}

243

244

@Test

245

void shouldGetProductList() {

246

// Seed test data

247

productRepository.save(new Product("Product 1", 10.0));

248

productRepository.save(new Product("Product 2", 20.0));

249

250

ResponseEntity<Product[]> response = restTemplate.getForEntity(

251

"/api/products", Product[].class);

252

253

assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);

254

assertThat(response.getBody()).hasSize(2);

255

}

256

}

257

```

258

259

### Test Security Configuration

260

261

Testing with Spring Security integration and authentication.

262

263

```java { .api }

264

/**

265

* Security testing with @WithMockUser

266

*/

267

@WebMvcTest(SecureController.class)

268

class SecureControllerTest {

269

270

@Autowired

271

private MockMvc mockMvc;

272

273

@Test

274

@WithMockUser(roles = "ADMIN")

275

void shouldAllowAdminAccess() throws Exception {

276

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

277

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

278

}

279

280

@Test

281

@WithMockUser(roles = "USER")

282

void shouldDenyUserAccess() throws Exception {

283

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

284

.andExpect(status().isForbidden());

285

}

286

287

@Test

288

void shouldRequireAuthentication() throws Exception {

289

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

290

.andExpect(status().isUnauthorized());

291

}

292

}

293

294

/**

295

* Custom security test user

296

*/

297

@WithMockUser(username = "testuser", roles = {"USER", "ADMIN"})

298

@Test

299

void shouldAllowCustomUser() throws Exception {

300

// Test with custom user

301

}

302

```

303

304

### Test Configuration and Profiles

305

306

Configure test-specific beans and properties.

307

308

```java { .api }

309

/**

310

* Test configuration class

311

*/

312

@TestConfiguration

313

public class TestConfig {

314

315

@Bean

316

@Primary

317

public Clock testClock() {

318

return Clock.fixed(Instant.parse("2023-01-01T00:00:00Z"), ZoneOffset.UTC);

319

}

320

321

@Bean

322

@Primary

323

public EmailService mockEmailService() {

324

return Mockito.mock(EmailService.class);

325

}

326

}

327

328

/**

329

* Import test configuration

330

*/

331

@WebMvcTest

332

@Import(TestConfig.class)

333

class ControllerWithTestConfigTest {

334

// Test with custom configuration

335

}

336

```

337

338

## Types

339

340

```java { .api }

341

// MockMvc for web layer testing

342

public class MockMvc {

343

public ResultActions perform(MockHttpServletRequestBuilder requestBuilder) throws Exception;

344

}

345

346

// Test result actions for chaining expectations

347

public interface ResultActions {

348

ResultActions andExpect(ResultMatcher matcher) throws Exception;

349

ResultActions andDo(ResultHandler handler) throws Exception;

350

MvcResult andReturn() throws Exception;

351

}

352

353

// Test RestTemplate for integration testing

354

public class TestRestTemplate {

355

public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables);

356

public <T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables);

357

public <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables);

358

}

359

360

// Test annotations

361

@Target(ElementType.TYPE)

362

@Retention(RetentionPolicy.RUNTIME)

363

@ExtendWith(SpringExtension.class)

364

public @interface WebMvcTest {

365

Class<?>[] value() default {};

366

Class<?>[] controllers() default {};

367

boolean useDefaultFilters() default true;

368

}

369

370

@Target({ElementType.TYPE})

371

@Retention(RetentionPolicy.RUNTIME)

372

@ExtendWith(SpringExtension.class)

373

public @interface SpringBootTest {

374

WebEnvironment webEnvironment() default WebEnvironment.MOCK;

375

376

enum WebEnvironment {

377

MOCK, RANDOM_PORT, DEFINED_PORT, NONE

378

}

379

}

380

381

// Mock annotations

382

@Target({ElementType.FIELD, ElementType.PARAMETER})

383

@Retention(RetentionPolicy.RUNTIME)

384

public @interface MockBean {

385

}

386

387

@Target({ElementType.FIELD, ElementType.PARAMETER})

388

@Retention(RetentionPolicy.RUNTIME)

389

public @interface SpyBean {

390

}

391

392

// Security testing annotation

393

@Target({ElementType.METHOD, ElementType.TYPE})

394

@Retention(RetentionPolicy.RUNTIME)

395

public @interface WithMockUser {

396

String value() default "user";

397

String username() default "";

398

String[] roles() default {"USER"};

399

String[] authorities() default {};

400

}

401

```