or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

argument-aggregation.mdargument-conversion.mdcore-testing.mdcsv-sources.mdcustom-sources.mdenum-method-sources.mdindex.mdvalue-sources.md

enum-method-sources.mddocs/

0

# Enum and Method Sources

1

2

Advanced argument providers for enum constants, method-generated arguments, and field-based data sources.

3

4

## Capabilities

5

6

### @EnumSource Annotation

7

8

Provides enum constants as test arguments with flexible selection modes and filtering options.

9

10

```java { .api }

11

/**

12

* Provides enum constants as arguments to parameterized tests

13

*/

14

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

15

@Retention(RetentionPolicy.RUNTIME)

16

@Documented

17

@API(status = STABLE, since = "5.0")

18

@ArgumentsSource(EnumArgumentsProvider.class)

19

@Repeatable(EnumSources.class)

20

@interface EnumSource {

21

/**

22

* Enum class to use (defaults to first parameter type if enum)

23

*/

24

Class<? extends Enum<?>> value() default Enum.class;

25

26

/**

27

* Specific enum constant names or regex patterns

28

*/

29

String[] names() default {};

30

31

/**

32

* Selection mode for filtering enum constants

33

*/

34

Mode mode() default INCLUDE;

35

36

/**

37

* Range start for enum constants (experimental)

38

*/

39

@API(status = EXPERIMENTAL, since = "5.12")

40

String from() default "";

41

42

/**

43

* Range end for enum constants (experimental)

44

*/

45

@API(status = EXPERIMENTAL, since = "5.12")

46

String to() default "";

47

48

/**

49

* Selection mode enum

50

*/

51

enum Mode {

52

/**

53

* Include only specified names (default)

54

*/

55

INCLUDE,

56

57

/**

58

* Exclude specified names

59

*/

60

EXCLUDE,

61

62

/**

63

* Include names matching all patterns

64

*/

65

MATCH_ALL,

66

67

/**

68

* Include names matching any pattern

69

*/

70

MATCH_ANY,

71

72

/**

73

* Exclude names matching patterns

74

*/

75

MATCH_NONE

76

}

77

}

78

```

79

80

**Usage Examples:**

81

82

```java

83

import org.junit.jupiter.params.ParameterizedTest;

84

import org.junit.jupiter.params.provider.EnumSource;

85

86

enum Planet {

87

MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE

88

}

89

90

enum Status {

91

ACTIVE, INACTIVE, PENDING, SUSPENDED

92

}

93

94

class EnumSourceExamples {

95

96

// All enum constants

97

@ParameterizedTest

98

@EnumSource(Planet.class)

99

void testAllPlanets(Planet planet) {

100

assertNotNull(planet);

101

assertNotNull(planet.name());

102

}

103

104

// Inferred enum type from parameter

105

@ParameterizedTest

106

@EnumSource

107

void testInferredEnum(Status status) {

108

assertNotNull(status);

109

}

110

111

// Specific enum constants

112

@ParameterizedTest

113

@EnumSource(value = Planet.class, names = {"EARTH", "MARS", "JUPITER"})

114

void testSpecificPlanets(Planet planet) {

115

assertTrue(planet == Planet.EARTH ||

116

planet == Planet.MARS ||

117

planet == Planet.JUPITER);

118

}

119

120

// Exclude specific constants

121

@ParameterizedTest

122

@EnumSource(value = Status.class, names = {"SUSPENDED"}, mode = EnumSource.Mode.EXCLUDE)

123

void testActiveStatuses(Status status) {

124

assertNotEquals(Status.SUSPENDED, status);

125

}

126

127

// Pattern matching - include

128

@ParameterizedTest

129

@EnumSource(value = Planet.class, names = {".*US$"}, mode = EnumSource.Mode.MATCH_ANY)

130

void testPlanetsEndingWithUs(Planet planet) {

131

// VENUS, URANUS

132

assertTrue(planet.name().endsWith("US"));

133

}

134

135

// Pattern matching - exclude

136

@ParameterizedTest

137

@EnumSource(value = Planet.class, names = {"^M.*"}, mode = EnumSource.Mode.MATCH_NONE)

138

void testPlanetsNotStartingWithM(Planet planet) {

139

// All except MERCURY, MARS

140

assertFalse(planet.name().startsWith("M"));

141

}

142

143

// Multiple patterns - match all

144

@ParameterizedTest

145

@EnumSource(value = Planet.class, names = {".*R.*", ".*N.*"}, mode = EnumSource.Mode.MATCH_ALL)

146

void testPlanetsWithRAndN(Planet planet) {

147

// SATURN, URANUS

148

assertTrue(planet.name().contains("R") && planet.name().contains("N"));

149

}

150

151

// Range selection (experimental)

152

@ParameterizedTest

153

@EnumSource(value = Planet.class, from = "EARTH", to = "JUPITER")

154

void testInnerPlanets(Planet planet) {

155

// EARTH, MARS, JUPITER

156

int ordinal = planet.ordinal();

157

assertTrue(ordinal >= Planet.EARTH.ordinal() &&

158

ordinal <= Planet.JUPITER.ordinal());

159

}

160

}

161

```

162

163

### @MethodSource Annotation

164

165

Provides arguments from factory method return values with support for various return types.

166

167

```java { .api }

168

/**

169

* Provides arguments from factory method return values

170

*/

171

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

172

@Retention(RetentionPolicy.RUNTIME)

173

@Documented

174

@API(status = STABLE, since = "5.0")

175

@ArgumentsSource(MethodArgumentsProvider.class)

176

@Repeatable(MethodSources.class)

177

@interface MethodSource {

178

/**

179

* Factory method names (defaults to test method name if empty)

180

*/

181

String[] value() default "";

182

}

183

```

184

185

**Usage Examples:**

186

187

```java

188

import org.junit.jupiter.params.ParameterizedTest;

189

import org.junit.jupiter.params.provider.MethodSource;

190

import org.junit.jupiter.params.provider.Arguments;

191

import java.util.stream.Stream;

192

import java.util.*;

193

194

class MethodSourceExamples {

195

196

// Method name matches test method name

197

@ParameterizedTest

198

@MethodSource

199

void testWithNumbers(int number) {

200

assertTrue(number > 0);

201

}

202

203

static Stream<Integer> testWithNumbers() {

204

return Stream.of(1, 2, 3, 5, 8);

205

}

206

207

// Explicit method name

208

@ParameterizedTest

209

@MethodSource("stringProvider")

210

void testWithStrings(String value) {

211

assertNotNull(value);

212

assertFalse(value.isEmpty());

213

}

214

215

static Stream<String> stringProvider() {

216

return Stream.of("apple", "banana", "cherry");

217

}

218

219

// Multiple arguments using Arguments.of()

220

@ParameterizedTest

221

@MethodSource("userProvider")

222

void testWithMultipleArgs(String name, int age, boolean active) {

223

assertNotNull(name);

224

assertTrue(age >= 0);

225

}

226

227

static Stream<Arguments> userProvider() {

228

return Stream.of(

229

Arguments.of("Alice", 25, true),

230

Arguments.of("Bob", 30, false),

231

Arguments.of("Charlie", 35, true)

232

);

233

}

234

235

// Collection return type

236

@ParameterizedTest

237

@MethodSource("listProvider")

238

void testWithList(String fruit) {

239

assertNotNull(fruit);

240

}

241

242

static List<String> listProvider() {

243

return Arrays.asList("apple", "banana", "cherry");

244

}

245

246

// Array return type

247

@ParameterizedTest

248

@MethodSource("arrayProvider")

249

void testWithArray(int value) {

250

assertTrue(value > 0);

251

}

252

253

static int[] arrayProvider() {

254

return new int[]{1, 2, 3, 4, 5};

255

}

256

257

// Object array for multiple parameters

258

@ParameterizedTest

259

@MethodSource("objectArrayProvider")

260

void testWithObjectArray(String name, double price) {

261

assertNotNull(name);

262

assertTrue(price > 0);

263

}

264

265

static Object[][] objectArrayProvider() {

266

return new Object[][]{

267

{"Apple", 1.50},

268

{"Banana", 0.75},

269

{"Cherry", 2.00}

270

};

271

}

272

273

// Iterator return type

274

@ParameterizedTest

275

@MethodSource("iteratorProvider")

276

void testWithIterator(String value) {

277

assertNotNull(value);

278

}

279

280

static Iterator<String> iteratorProvider() {

281

return Arrays.asList("one", "two", "three").iterator();

282

}

283

284

// Multiple method sources

285

@ParameterizedTest

286

@MethodSource({"positiveNumbers", "negativeNumbers"})

287

void testWithMultipleSources(int number) {

288

assertNotEquals(0, number);

289

}

290

291

static Stream<Integer> positiveNumbers() {

292

return Stream.of(1, 2, 3);

293

}

294

295

static Stream<Integer> negativeNumbers() {

296

return Stream.of(-1, -2, -3);

297

}

298

299

// External class method source

300

@ParameterizedTest

301

@MethodSource("com.example.TestDataProvider#providePairs")

302

void testWithExternalSource(String key, String value) {

303

assertNotNull(key);

304

assertNotNull(value);

305

}

306

307

// Complex data structures

308

@ParameterizedTest

309

@MethodSource("complexDataProvider")

310

void testWithComplexData(Map<String, Object> data) {

311

assertNotNull(data);

312

assertFalse(data.isEmpty());

313

}

314

315

static Stream<Map<String, Object>> complexDataProvider() {

316

return Stream.of(

317

Map.of("name", "Product A", "price", 19.99, "available", true),

318

Map.of("name", "Product B", "price", 29.50, "available", false)

319

);

320

}

321

}

322

```

323

324

### @FieldSource Annotation

325

326

Provides arguments from field values (experimental feature since JUnit 5.11).

327

328

```java { .api }

329

/**

330

* Provides arguments from field values (experimental)

331

*/

332

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

333

@Retention(RetentionPolicy.RUNTIME)

334

@Documented

335

@API(status = EXPERIMENTAL, since = "5.11")

336

@ArgumentsSource(FieldArgumentsProvider.class)

337

@Repeatable(FieldSources.class)

338

@interface FieldSource {

339

/**

340

* Field names (defaults to test method name if empty)

341

*/

342

String[] value() default "";

343

}

344

```

345

346

**Usage Examples:**

347

348

```java

349

import org.junit.jupiter.params.ParameterizedTest;

350

import org.junit.jupiter.params.provider.FieldSource;

351

import org.junit.jupiter.params.provider.Arguments;

352

import java.util.function.Supplier;

353

import java.util.stream.Stream;

354

import java.util.*;

355

356

class FieldSourceExamples {

357

358

// Static field with same name as test method

359

static List<String> testWithFieldData = Arrays.asList("apple", "banana", "cherry");

360

361

@ParameterizedTest

362

@FieldSource

363

void testWithFieldData(String fruit) {

364

assertNotNull(fruit);

365

}

366

367

// Explicit field name

368

static int[] numbers = {1, 2, 3, 5, 8};

369

370

@ParameterizedTest

371

@FieldSource("numbers")

372

void testWithNumbers(int number) {

373

assertTrue(number > 0);

374

}

375

376

// Field containing Arguments

377

static List<Arguments> userTestData = Arrays.asList(

378

Arguments.of("Alice", 25, true),

379

Arguments.of("Bob", 30, false),

380

Arguments.of("Charlie", 35, true)

381

);

382

383

@ParameterizedTest

384

@FieldSource("userTestData")

385

void testWithUserData(String name, int age, boolean active) {

386

assertNotNull(name);

387

assertTrue(age >= 0);

388

}

389

390

// Supplier field for lazy evaluation

391

static Supplier<Stream<String>> lazyStringProvider = () ->

392

Stream.of("lazy1", "lazy2", "lazy3");

393

394

@ParameterizedTest

395

@FieldSource("lazyStringProvider")

396

void testWithLazyField(String value) {

397

assertNotNull(value);

398

assertTrue(value.startsWith("lazy"));

399

}

400

401

// Multiple fields

402

static List<String> fruits = Arrays.asList("apple", "banana");

403

static List<String> vegetables = Arrays.asList("carrot", "broccoli");

404

405

@ParameterizedTest

406

@FieldSource({"fruits", "vegetables"})

407

void testWithMultipleFields(String item) {

408

assertNotNull(item);

409

}

410

411

// External class field

412

@ParameterizedTest

413

@FieldSource("com.example.TestData#testValues")

414

void testWithExternalField(String value) {

415

assertNotNull(value);

416

}

417

}

418

```

419

420

### Container Annotations

421

422

Container annotations for multiple enum and method source annotations.

423

424

```java { .api }

425

/**

426

* Container annotation for multiple @EnumSource annotations

427

*/

428

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

429

@Retention(RetentionPolicy.RUNTIME)

430

@Documented

431

@API(status = STABLE, since = "5.0")

432

@interface EnumSources {

433

EnumSource[] value();

434

}

435

436

/**

437

* Container annotation for multiple @MethodSource annotations

438

*/

439

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

440

@Retention(RetentionPolicy.RUNTIME)

441

@Documented

442

@API(status = STABLE, since = "5.0")

443

@interface MethodSources {

444

MethodSource[] value();

445

}

446

447

/**

448

* Container annotation for multiple @FieldSource annotations

449

*/

450

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

451

@Retention(RetentionPolicy.RUNTIME)

452

@Documented

453

@API(status = EXPERIMENTAL, since = "5.11")

454

@interface FieldSources {

455

FieldSource[] value();

456

}

457

```

458

459

### Advanced Patterns

460

461

**Complex Method Source Patterns:**

462

463

```java

464

class AdvancedMethodSourceExamples {

465

466

// Parameterized test with test case names

467

@ParameterizedTest(name = "Test case: {0}")

468

@MethodSource("namedTestCases")

469

void testWithNamedCases(String testCase, int input, int expected) {

470

// Test implementation using testCase description

471

assertNotNull(testCase);

472

assertTrue(input >= 0);

473

assertTrue(expected >= 0);

474

}

475

476

static Stream<Arguments> namedTestCases() {

477

return Stream.of(

478

Arguments.of("Square root of 4", 4, 2),

479

Arguments.of("Square root of 9", 9, 3),

480

Arguments.of("Square root of 16", 16, 4)

481

);

482

}

483

484

// Dynamic data generation

485

@ParameterizedTest

486

@MethodSource("dynamicDataProvider")

487

void testWithDynamicData(int value) {

488

assertTrue(value > 0);

489

}

490

491

static Stream<Integer> dynamicDataProvider() {

492

return Stream.iterate(1, n -> n < 100, n -> n * 2);

493

}

494

495

// Combining different data sources

496

@ParameterizedTest

497

@MethodSource("combinedDataProvider")

498

void testWithCombinedData(String type, Object value) {

499

assertNotNull(type);

500

assertNotNull(value);

501

}

502

503

static Stream<Arguments> combinedDataProvider() {

504

return Stream.concat(

505

Stream.of("string").map(s -> Arguments.of("String", s)),

506

Stream.of(42).map(i -> Arguments.of("Integer", i))

507

);

508

}

509

}

510

```

511

512

These advanced source types provide powerful capabilities for data-driven testing, enabling complex test scenarios with enum-based logic, dynamic data generation, and external data sources.