or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration-overrides.mdcore-test-support.mddao-testing.mdindex.mdjunit5-extensions.mdresource-testing.md

resource-testing.mddocs/

0

# Resource Testing

1

2

Lightweight JAX-RS resource testing utilities providing isolated testing environment without full Dropwizard application bootstrap. Perfect for unit testing individual REST endpoints with minimal overhead and fast execution.

3

4

## Capabilities

5

6

### Resource

7

8

Core utility class for creating isolated JAX-RS resource testing environments with configurable Jackson ObjectMapper, Bean Validation, and Jersey providers.

9

10

```java { .api }

11

/**

12

* Utility class for isolated JAX-RS resource testing

13

*/

14

public class Resource {

15

16

/**

17

* Create a new Resource builder for configuration

18

* @return Builder instance for fluent configuration

19

*/

20

public static Builder builder();

21

22

/**

23

* Get a JAX-RS WebTarget for making HTTP requests to resources

24

* @param path Path to append to base URI

25

* @return WebTarget for the specified path

26

*/

27

public WebTarget target(String path);

28

29

/**

30

* Get the underlying JAX-RS Client for advanced HTTP operations

31

* @return JAX-RS Client instance

32

*/

33

public Client client();

34

35

/**

36

* Get the underlying JerseyTest instance for advanced testing

37

* @return JerseyTest instance managing the test environment

38

*/

39

public JerseyTest getJerseyTest();

40

41

/**

42

* Get the Bean Validator used by the resource testing environment

43

* @return Validator instance for bean validation

44

*/

45

public Validator getValidator();

46

47

/**

48

* Get the Jackson ObjectMapper used for JSON serialization/deserialization

49

* @return ObjectMapper instance

50

*/

51

public ObjectMapper getObjectMapper();

52

53

/**

54

* Get the client configurator for custom client setup

55

* @return Consumer for ClientConfig customization

56

*/

57

public Consumer<ClientConfig> getClientConfigurator();

58

59

// Lifecycle methods

60

/**

61

* Initialize the resource testing environment before tests

62

* @throws Exception if initialization fails

63

*/

64

public void before() throws Exception;

65

66

/**

67

* Cleanup the resource testing environment after tests

68

* @throws Exception if cleanup fails

69

*/

70

public void after() throws Exception;

71

}

72

```

73

74

### Resource.Builder

75

76

Fluent builder for configuring Resource testing environments with custom ObjectMapper, validators, providers, and Jersey settings.

77

78

```java { .api }

79

/**

80

* Fluent builder for Resource configuration

81

*/

82

public static class Builder<B extends Builder<B>> {

83

84

// Resource configuration

85

/**

86

* Add a JAX-RS resource instance to the testing environment

87

* @param resource Resource instance to add

88

* @return Builder instance for chaining

89

*/

90

public B addResource(Object resource);

91

92

/**

93

* Add a JAX-RS resource using a supplier for lazy initialization

94

* @param resourceSupplier Supplier providing the resource instance

95

* @return Builder instance for chaining

96

*/

97

public B addResource(Supplier<Object> resourceSupplier);

98

99

// Provider configuration

100

/**

101

* Add a JAX-RS provider class to the testing environment

102

* @param klass Provider class to register

103

* @return Builder instance for chaining

104

*/

105

public B addProvider(Class<?> klass);

106

107

/**

108

* Add a JAX-RS provider instance to the testing environment

109

* @param provider Provider instance to register

110

* @return Builder instance for chaining

111

*/

112

public B addProvider(Object provider);

113

114

// Component customization

115

/**

116

* Set a custom Jackson ObjectMapper for JSON processing

117

* @param mapper Custom ObjectMapper instance

118

* @return Builder instance for chaining

119

*/

120

public B setMapper(ObjectMapper mapper);

121

122

/**

123

* Set a custom MetricRegistry for metrics collection

124

* @param metricRegistry Custom MetricRegistry instance

125

* @return Builder instance for chaining

126

*/

127

public B setMetricRegistry(MetricRegistry metricRegistry);

128

129

/**

130

* Set a custom Bean Validator for request/response validation

131

* @param validator Custom Validator instance

132

* @return Builder instance for chaining

133

*/

134

public B setValidator(Validator validator);

135

136

// Jersey configuration

137

/**

138

* Set a custom client configurator for HTTP client setup

139

* @param clientConfigurator Consumer for ClientConfig customization

140

* @return Builder instance for chaining

141

*/

142

public B setClientConfigurator(Consumer<ClientConfig> clientConfigurator);

143

144

/**

145

* Add a Jersey property to the testing environment

146

* @param property Property name

147

* @param value Property value

148

* @return Builder instance for chaining

149

*/

150

public B addProperty(String property, Object value);

151

152

/**

153

* Set a custom TestContainerFactory for Jersey testing

154

* @param factory Custom TestContainerFactory instance

155

* @return Builder instance for chaining

156

*/

157

public B setTestContainerFactory(TestContainerFactory factory);

158

159

/**

160

* Configure whether to register default exception mappers

161

* @param value true to register default exception mappers, false otherwise

162

* @return Builder instance for chaining

163

*/

164

public B setRegisterDefaultExceptionMappers(boolean value);

165

166

/**

167

* Configure whether to bootstrap Logback logging

168

* @param value true to bootstrap logging, false otherwise

169

* @return Builder instance for chaining

170

*/

171

public B bootstrapLogging(boolean value);

172

173

/**

174

* Build the configured Resource instance

175

* @return Configured Resource instance ready for testing

176

*/

177

public Resource build();

178

}

179

```

180

181

**Usage Examples:**

182

183

```java

184

// Basic resource testing

185

@RegisterExtension

186

public static final ResourceExtension RESOURCE = ResourceExtension.builder()

187

.addResource(new UserResource())

188

.build();

189

190

@Test

191

public void testGetUser() {

192

User user = RESOURCE.target("/users/123")

193

.request(MediaType.APPLICATION_JSON)

194

.get(User.class);

195

196

assertThat(user.getId()).isEqualTo(123);

197

}

198

199

// With custom ObjectMapper and providers

200

@RegisterExtension

201

public static final ResourceExtension RESOURCE = ResourceExtension.builder()

202

.addResource(new UserResource())

203

.addProvider(new CustomExceptionMapper())

204

.addProvider(new ValidationFeature())

205

.setMapper(createCustomObjectMapper())

206

.build();

207

208

// With multiple resources and shared dependencies

209

UserService userService = mock(UserService.class);

210

EmailService emailService = mock(EmailService.class);

211

212

@RegisterExtension

213

public static final ResourceExtension RESOURCE = ResourceExtension.builder()

214

.addResource(new UserResource(userService))

215

.addResource(new EmailResource(emailService))

216

.addProvider(new AuthenticationFilter())

217

.setValidator(Validation.buildDefaultValidatorFactory().getValidator())

218

.build();

219

220

// Advanced configuration with custom client setup

221

@RegisterExtension

222

public static final ResourceExtension RESOURCE = ResourceExtension.builder()

223

.addResource(new ApiResource())

224

.setClientConfigurator(clientConfig -> {

225

clientConfig.register(new LoggingFeature());

226

clientConfig.property(ClientProperties.CONNECT_TIMEOUT, 5000);

227

clientConfig.property(ClientProperties.READ_TIMEOUT, 10000);

228

})

229

.addProperty(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true)

230

.build();

231

232

@Test

233

public void testResourceValidation() {

234

Response response = RESOURCE.target("/api/users")

235

.request()

236

.post(Entity.json("{ \"invalid\": \"data\" }"));

237

238

assertThat(response.getStatus()).isEqualTo(400);

239

240

ValidationErrorResponse error = response.readEntity(ValidationErrorResponse.class);

241

assertThat(error.getErrors()).isNotEmpty();

242

}

243

244

// Testing with different content types

245

@Test

246

public void testContentNegotiation() {

247

// JSON request/response

248

User jsonUser = RESOURCE.target("/users/123")

249

.request(MediaType.APPLICATION_JSON)

250

.get(User.class);

251

252

// XML request/response

253

User xmlUser = RESOURCE.target("/users/123")

254

.request(MediaType.APPLICATION_XML)

255

.get(User.class);

256

257

assertThat(jsonUser).isEqualTo(xmlUser);

258

}

259

260

// Testing error handling

261

@Test

262

public void testErrorHandling() {

263

Response response = RESOURCE.target("/users/999")

264

.request()

265

.get();

266

267

assertThat(response.getStatus()).isEqualTo(404);

268

269

ErrorResponse error = response.readEntity(ErrorResponse.class);

270

assertThat(error.getMessage()).contains("User not found");

271

}

272

```

273

274

### DropwizardClient

275

276

Lightweight HTTP client testing utility providing minimal Dropwizard setup for testing HTTP interactions without full application bootstrap.

277

278

```java { .api }

279

/**

280

* Lightweight HTTP client for testing REST endpoints

281

*/

282

public class DropwizardClient {

283

284

/**

285

* Create DropwizardClient with JAX-RS resources

286

* @param resources JAX-RS resource instances to register

287

*/

288

public DropwizardClient(Object... resources);

289

290

/**

291

* Get the base URI for HTTP requests to the test server

292

* @return Base URI including scheme, host, and port

293

*/

294

public URI baseUri();

295

296

/**

297

* Get the Jackson ObjectMapper used by the client

298

* @return ObjectMapper instance for JSON processing

299

*/

300

public ObjectMapper getObjectMapper();

301

302

/**

303

* Get the Dropwizard Environment instance

304

* @return Environment with access to metrics, validation, etc.

305

*/

306

public Environment getEnvironment();

307

308

// Lifecycle methods

309

/**

310

* Initialize the client testing environment before tests

311

* @throws Exception if initialization fails

312

*/

313

public void before() throws Exception;

314

315

/**

316

* Cleanup the client testing environment after tests

317

* @throws Exception if cleanup fails

318

*/

319

public void after() throws Exception;

320

}

321

```

322

323

**Usage Examples:**

324

325

```java

326

// Manual client setup

327

DropwizardClient client = new DropwizardClient(

328

new UserResource(),

329

new OrderResource()

330

);

331

332

@BeforeEach

333

public void setUp() throws Exception {

334

client.before();

335

}

336

337

@AfterEach

338

public void tearDown() throws Exception {

339

client.after();

340

}

341

342

@Test

343

public void testWithHttpClient() {

344

URI baseUri = client.baseUri();

345

346

// Use any HTTP client library

347

String response = HttpClient.newHttpClient()

348

.send(HttpRequest.newBuilder()

349

.uri(baseUri.resolve("/users"))

350

.build(),

351

HttpResponse.BodyHandlers.ofString())

352

.body();

353

354

assertThat(response).contains("users");

355

}

356

357

// With OkHttp client

358

@Test

359

public void testWithOkHttp() {

360

OkHttpClient httpClient = new OkHttpClient();

361

Request request = new Request.Builder()

362

.url(client.baseUri().resolve("/users").toString())

363

.build();

364

365

try (okhttp3.Response response = httpClient.newCall(request).execute()) {

366

assertThat(response.isSuccessful()).isTrue();

367

String body = response.body().string();

368

assertThat(body).isNotNull();

369

}

370

}

371

```

372

373

## Common Testing Patterns

374

375

### Resource Validation Testing

376

377

```java

378

@RegisterExtension

379

public static final ResourceExtension RESOURCE = ResourceExtension.builder()

380

.addResource(new UserResource())

381

.setRegisterDefaultExceptionMappers(true)

382

.build();

383

384

@Test

385

public void testValidationErrors() {

386

// Invalid user data

387

User invalidUser = new User();

388

invalidUser.setEmail("invalid-email");

389

390

Response response = RESOURCE.target("/users")

391

.request()

392

.post(Entity.json(invalidUser));

393

394

assertThat(response.getStatus()).isEqualTo(422);

395

396

ValidationErrorMessage error = response.readEntity(ValidationErrorMessage.class);

397

assertThat(error.getErrors()).containsKey("email");

398

}

399

```

400

401

### Exception Mapper Testing

402

403

```java

404

@RegisterExtension

405

public static final ResourceExtension RESOURCE = ResourceExtension.builder()

406

.addResource(new UserResource())

407

.addProvider(new CustomExceptionMapper())

408

.build();

409

410

@Test

411

public void testCustomExceptionHandling() {

412

Response response = RESOURCE.target("/users/trigger-custom-exception")

413

.request()

414

.get();

415

416

assertThat(response.getStatus()).isEqualTo(418);

417

assertThat(response.getHeaderString("X-Custom-Error")).isEqualTo("true");

418

}

419

```

420

421

### Authentication Filter Testing

422

423

```java

424

@RegisterExtension

425

public static final ResourceExtension RESOURCE = ResourceExtension.builder()

426

.addResource(new SecureResource())

427

.addProvider(new AuthenticationFilter())

428

.build();

429

430

@Test

431

public void testAuthenticationRequired() {

432

Response response = RESOURCE.target("/secure/data")

433

.request()

434

.get();

435

436

assertThat(response.getStatus()).isEqualTo(401);

437

}

438

439

@Test

440

public void testAuthenticatedAccess() {

441

Response response = RESOURCE.target("/secure/data")

442

.request()

443

.header("Authorization", "Bearer valid-token")

444

.get();

445

446

assertThat(response.getStatus()).isEqualTo(200);

447

}

448

```