0
# Java 8+ Assertions
1
2
Modern Java type support for Optional, Stream, and primitive optional types with appropriate assertion methods.
3
4
## Capabilities
5
6
### Optional Assertions
7
8
Assertions for Java 8+ Optional types providing comprehensive validation of optional values.
9
10
```java { .api }
11
/**
12
* Creates an OptionalSubject for asserting about Optional values.
13
* @param actual the Optional under test
14
*/
15
public static OptionalSubject assertThat(Optional<?> actual);
16
```
17
18
#### Core Optional Methods
19
20
Methods for basic Optional state validation.
21
22
```java { .api }
23
/**
24
* Fails if the Optional is not present (i.e., isEmpty() returns true).
25
*/
26
public void isPresent();
27
28
/**
29
* Fails if the Optional is present (i.e., isPresent() returns true).
30
*/
31
public void isEmpty();
32
33
/**
34
* Fails if the Optional does not have the given value.
35
* @param expected the expected value that should be present
36
*/
37
public void hasValue(Object expected);
38
```
39
40
**Usage Examples:**
41
42
```java
43
// Basic Optional validation
44
Optional<String> presentValue = Optional.of("hello");
45
assertThat(presentValue).isPresent();
46
assertThat(presentValue).hasValue("hello");
47
48
Optional<String> emptyValue = Optional.empty();
49
assertThat(emptyValue).isEmpty();
50
51
// Testing Optional in service methods
52
Optional<User> userResult = userService.findById(123L);
53
assertThat(userResult).isPresent();
54
assertThat(userResult).hasValue(expectedUser);
55
```
56
57
#### Advanced Optional Patterns
58
59
Real-world patterns for testing Optional usage in applications.
60
61
```java
62
// Testing Optional chaining
63
@Test
64
public void testOptionalChaining() {
65
Optional<String> result = userService.findById(123L)
66
.map(User::getEmail)
67
.filter(email -> email.contains("@"))
68
.map(String::toLowerCase);
69
70
assertThat(result).isPresent();
71
assertThat(result).hasValue("user@example.com");
72
}
73
74
// Testing Optional with business logic
75
@Test
76
public void testOptionalBusinessLogic() {
77
// When user exists
78
Optional<User> existingUser = userService.findByEmail("existing@example.com");
79
assertThat(existingUser).isPresent();
80
81
// When user doesn't exist
82
Optional<User> nonExistentUser = userService.findByEmail("missing@example.com");
83
assertThat(nonExistentUser).isEmpty();
84
}
85
86
// Testing Optional transformation
87
@Test
88
public void testOptionalTransformation() {
89
Optional<String> input = Optional.of(" HELLO WORLD ");
90
Optional<String> result = input
91
.map(String::trim)
92
.map(String::toLowerCase)
93
.filter(s -> s.length() > 5);
94
95
assertThat(result).isPresent();
96
assertThat(result).hasValue("hello world");
97
}
98
```
99
100
### Primitive Optional Assertions
101
102
Specialized assertions for primitive Optional types with appropriate type-safe methods.
103
104
#### OptionalInt Assertions
105
106
```java { .api }
107
/**
108
* Creates an OptionalIntSubject for asserting about OptionalInt values.
109
* @param actual the OptionalInt under test
110
*/
111
public static OptionalIntSubject assertThat(OptionalInt actual);
112
113
/**
114
* Fails if the OptionalInt is not present.
115
*/
116
public void isPresent();
117
118
/**
119
* Fails if the OptionalInt is present.
120
*/
121
public void isEmpty();
122
123
/**
124
* Fails if the OptionalInt does not have the given value.
125
* @param expected the expected int value that should be present
126
*/
127
public void hasValue(int expected);
128
```
129
130
**Usage Examples:**
131
132
```java
133
// Basic OptionalInt usage
134
OptionalInt presentInt = OptionalInt.of(42);
135
assertThat(presentInt).isPresent();
136
assertThat(presentInt).hasValue(42);
137
138
OptionalInt emptyInt = OptionalInt.empty();
139
assertThat(emptyInt).isEmpty();
140
141
// Testing OptionalInt from streams
142
int[] numbers = {1, 2, 3, 4, 5};
143
OptionalInt max = Arrays.stream(numbers).max();
144
assertThat(max).isPresent();
145
assertThat(max).hasValue(5);
146
147
OptionalInt firstEven = Arrays.stream(numbers)
148
.filter(n -> n % 2 == 0)
149
.findFirst();
150
assertThat(firstEven).isPresent();
151
assertThat(firstEven).hasValue(2);
152
```
153
154
#### OptionalLong Assertions
155
156
```java { .api }
157
/**
158
* Creates an OptionalLongSubject for asserting about OptionalLong values.
159
* @param actual the OptionalLong under test
160
*/
161
public static OptionalLongSubject assertThat(OptionalLong actual);
162
163
/**
164
* Fails if the OptionalLong is not present.
165
*/
166
public void isPresent();
167
168
/**
169
* Fails if the OptionalLong is present.
170
*/
171
public void isEmpty();
172
173
/**
174
* Fails if the OptionalLong does not have the given value.
175
* @param expected the expected long value that should be present
176
*/
177
public void hasValue(long expected);
178
```
179
180
**Usage Examples:**
181
182
```java
183
// Testing OptionalLong with timestamps
184
List<Long> timestamps = Arrays.asList(1000000L, 2000000L, 3000000L);
185
OptionalLong maxTimestamp = timestamps.stream().mapToLong(Long::longValue).max();
186
assertThat(maxTimestamp).isPresent();
187
assertThat(maxTimestamp).hasValue(3000000L);
188
189
// Testing empty OptionalLong
190
OptionalLong emptyResult = LongStream.empty().findAny();
191
assertThat(emptyResult).isEmpty();
192
```
193
194
#### OptionalDouble Assertions
195
196
```java { .api }
197
/**
198
* Creates an OptionalDoubleSubject for asserting about OptionalDouble values.
199
* @param actual the OptionalDouble under test
200
*/
201
public static OptionalDoubleSubject assertThat(OptionalDouble actual);
202
203
/**
204
* Fails if the OptionalDouble is not present.
205
*/
206
public void isPresent();
207
208
/**
209
* Fails if the OptionalDouble is present.
210
*/
211
public void isEmpty();
212
213
/**
214
* Fails if the OptionalDouble does not have the given value.
215
* @param expected the expected double value that should be present
216
*/
217
public void hasValue(double expected);
218
```
219
220
**Usage Examples:**
221
222
```java
223
// Testing OptionalDouble with calculations
224
double[] measurements = {1.1, 2.2, 3.3, 4.4};
225
OptionalDouble average = Arrays.stream(measurements).average();
226
assertThat(average).isPresent();
227
// Note: For floating-point comparisons, consider using tolerance
228
// assertThat(average.getAsDouble()).isWithin(0.001).of(2.75);
229
230
// Testing empty OptionalDouble
231
OptionalDouble emptyAverage = DoubleStream.empty().average();
232
assertThat(emptyAverage).isEmpty();
233
```
234
235
### Stream Assertions
236
237
Comprehensive assertions for Java 8+ Stream types with collection-like functionality.
238
239
```java { .api }
240
/**
241
* Creates a StreamSubject for asserting about Stream values.
242
* @param actual the Stream under test
243
*/
244
public static StreamSubject assertThat(Stream<?> actual);
245
```
246
247
#### Core Stream Methods
248
249
Methods for basic Stream validation including size, emptiness, and content.
250
251
```java { .api }
252
/**
253
* Fails if the stream is not empty.
254
*/
255
public void isEmpty();
256
257
/**
258
* Fails if the stream is empty.
259
*/
260
public void isNotEmpty();
261
262
/**
263
* Fails if the stream does not have the given size.
264
* @param expectedSize the expected number of elements
265
*/
266
public void hasSize(int expectedSize);
267
268
/**
269
* Fails if the stream does not contain exactly the given elements, in any order.
270
* @param elements the expected elements
271
*/
272
public Ordered containsExactly(Object... elements);
273
274
/**
275
* Fails if the stream does not contain exactly the elements in the given iterable, in any order.
276
* @param expected the iterable containing expected elements
277
*/
278
public Ordered containsExactlyElementsIn(Iterable<?> expected);
279
```
280
281
**Usage Examples:**
282
283
```java
284
// Basic stream validation
285
Stream<String> fruits = Stream.of("apple", "banana", "cherry");
286
assertThat(fruits).hasSize(3);
287
assertThat(fruits).containsExactly("apple", "banana", "cherry");
288
289
// Testing empty streams
290
Stream<Integer> emptyStream = Stream.empty();
291
assertThat(emptyStream).isEmpty();
292
293
// Testing filtered streams
294
Stream<Integer> evenNumbers = Stream.of(1, 2, 3, 4, 5, 6)
295
.filter(n -> n % 2 == 0);
296
assertThat(evenNumbers).containsExactly(2, 4, 6);
297
```
298
299
#### Advanced Stream Testing Patterns
300
301
Real-world patterns for testing Stream operations and transformations.
302
303
```java
304
// Testing stream transformations
305
@Test
306
public void testStreamTransformation() {
307
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
308
309
Stream<String> upperCaseNames = names.stream()
310
.map(String::toUpperCase)
311
.filter(name -> name.length() > 3);
312
313
assertThat(upperCaseNames).containsExactly("ALICE", "CHARLIE");
314
}
315
316
// Testing stream reductions
317
@Test
318
public void testStreamReduction() {
319
Stream<Integer> numbers = Stream.of(1, 2, 3, 4, 5);
320
321
// Note: Stream can only be consumed once, so create fresh streams for each test
322
int sum = Stream.of(1, 2, 3, 4, 5).mapToInt(Integer::intValue).sum();
323
assertThat(sum).isEqualTo(15);
324
325
Optional<Integer> max = Stream.of(1, 2, 3, 4, 5).max(Integer::compareTo);
326
assertThat(max).isPresent();
327
assertThat(max).hasValue(5);
328
}
329
330
// Testing stream grouping and collecting
331
@Test
332
public void testStreamGrouping() {
333
List<String> words = Arrays.asList("apple", "banana", "apricot", "blueberry");
334
335
Map<Character, List<String>> groupedByFirstLetter = words.stream()
336
.collect(Collectors.groupingBy(word -> word.charAt(0)));
337
338
assertThat(groupedByFirstLetter).containsKey('a');
339
assertThat(groupedByFirstLetter).containsKey('b');
340
assertThat(groupedByFirstLetter.get('a')).containsExactly("apple", "apricot");
341
assertThat(groupedByFirstLetter.get('b')).containsExactly("banana", "blueberry");
342
}
343
```
344
345
### Primitive Stream Assertions
346
347
Specialized assertions for primitive stream types.
348
349
#### IntStream Assertions
350
351
```java { .api }
352
/**
353
* Creates an IntStreamSubject for asserting about IntStream values.
354
* @param actual the IntStream under test
355
*/
356
public static IntStreamSubject assertThat(IntStream actual);
357
```
358
359
**Usage Examples:**
360
361
```java
362
// Testing IntStream operations
363
IntStream numbers = IntStream.range(1, 6); // 1, 2, 3, 4, 5
364
assertThat(numbers).hasSize(5);
365
assertThat(numbers).containsExactly(1, 2, 3, 4, 5).inOrder();
366
367
// Testing IntStream transformations
368
IntStream evenSquares = IntStream.range(1, 11)
369
.filter(n -> n % 2 == 0)
370
.map(n -> n * n);
371
assertThat(evenSquares).containsExactly(4, 16, 36, 64, 100);
372
373
// Testing IntStream statistics
374
IntStream.Builder builder = IntStream.builder();
375
IntStream data = builder.add(10).add(20).add(30).build();
376
assertThat(data).hasSize(3);
377
```
378
379
#### LongStream Assertions
380
381
```java { .api }
382
/**
383
* Creates a LongStreamSubject for asserting about LongStream values.
384
* @param actual the LongStream under test
385
*/
386
public static LongStreamSubject assertThat(LongStream actual);
387
```
388
389
**Usage Examples:**
390
391
```java
392
// Testing LongStream with large numbers
393
LongStream largeNumbers = LongStream.of(1000000L, 2000000L, 3000000L);
394
assertThat(largeNumbers).hasSize(3);
395
assertThat(largeNumbers).containsExactly(1000000L, 2000000L, 3000000L).inOrder();
396
397
// Testing LongStream range operations
398
LongStream range = LongStream.rangeClosed(100L, 105L);
399
assertThat(range).containsExactly(100L, 101L, 102L, 103L, 104L, 105L).inOrder();
400
```
401
402
### Stream Testing Best Practices
403
404
#### Handling Stream Consumption
405
406
```java
407
// Remember: Streams can only be consumed once
408
@Test
409
public void testStreamConsumption() {
410
Supplier<Stream<String>> streamSupplier = () ->
411
Stream.of("apple", "banana", "cherry");
412
413
// Test size
414
assertThat(streamSupplier.get()).hasSize(3);
415
416
// Test contents (need fresh stream)
417
assertThat(streamSupplier.get()).containsExactly("apple", "banana", "cherry");
418
419
// Test filtered contents (need fresh stream)
420
assertThat(streamSupplier.get().filter(s -> s.contains("a")))
421
.containsExactly("apple", "banana");
422
}
423
```
424
425
#### Testing Parallel Streams
426
427
```java
428
// Testing parallel stream operations
429
@Test
430
public void testParallelStreamProcessing() {
431
List<Integer> numbers = IntStream.range(1, 1001)
432
.boxed()
433
.collect(Collectors.toList());
434
435
Stream<Integer> parallelSquares = numbers.parallelStream()
436
.map(n -> n * n)
437
.filter(n -> n > 100);
438
439
// Note: Parallel streams may not preserve order
440
assertThat(parallelSquares).isNotEmpty();
441
442
// For ordered assertions with parallel streams, use collect first
443
List<Integer> result = numbers.parallelStream()
444
.map(n -> n * n)
445
.filter(n -> n <= 25)
446
.sorted()
447
.collect(Collectors.toList());
448
449
assertThat(result).containsExactly(1, 4, 9, 16, 25).inOrder();
450
}
451
```
452
453
#### Integration with Optional
454
455
```java
456
// Testing Stream operations that produce Optional
457
@Test
458
public void testStreamOptionalIntegration() {
459
List<String> words = Arrays.asList("cat", "elephant", "dog", "hippopotamus");
460
461
Optional<String> longestWord = words.stream()
462
.max(Comparator.comparing(String::length));
463
464
assertThat(longestWord).isPresent();
465
assertThat(longestWord).hasValue("hippopotamus");
466
467
Optional<String> shortestWordStartingWithZ = words.stream()
468
.filter(word -> word.startsWith("z"))
469
.min(Comparator.comparing(String::length));
470
471
assertThat(shortestWordStartingWithZ).isEmpty();
472
}
473
```
474
475
## Types
476
477
```java { .api }
478
/**
479
* Subject class for making assertions about Optional values.
480
*/
481
public class OptionalSubject extends Subject {
482
/**
483
* Constructor for OptionalSubject.
484
* @param metadata failure metadata for context
485
* @param actual the Optional under test
486
*/
487
protected OptionalSubject(FailureMetadata metadata, Optional<?> actual);
488
489
/**
490
* Fails if the Optional is not present.
491
*/
492
public void isPresent();
493
494
/**
495
* Fails if the Optional is present.
496
*/
497
public void isEmpty();
498
499
/**
500
* Fails if the Optional does not have the given value.
501
* @param expected the expected value
502
*/
503
public void hasValue(Object expected);
504
}
505
506
/**
507
* Subject class for making assertions about OptionalInt values.
508
*/
509
public class OptionalIntSubject extends Subject {
510
protected OptionalIntSubject(FailureMetadata metadata, OptionalInt actual);
511
512
public void isPresent();
513
public void isEmpty();
514
public void hasValue(int expected);
515
}
516
517
/**
518
* Subject class for making assertions about OptionalLong values.
519
*/
520
public class OptionalLongSubject extends Subject {
521
protected OptionalLongSubject(FailureMetadata metadata, OptionalLong actual);
522
523
public void isPresent();
524
public void isEmpty();
525
public void hasValue(long expected);
526
}
527
528
/**
529
* Subject class for making assertions about OptionalDouble values.
530
*/
531
public class OptionalDoubleSubject extends Subject {
532
protected OptionalDoubleSubject(FailureMetadata metadata, OptionalDouble actual);
533
534
public void isPresent();
535
public void isEmpty();
536
public void hasValue(double expected);
537
}
538
539
/**
540
* Subject class for making assertions about Stream values.
541
*/
542
public class StreamSubject extends Subject {
543
/**
544
* Constructor for StreamSubject.
545
* @param metadata failure metadata for context
546
* @param actual the Stream under test
547
*/
548
protected StreamSubject(FailureMetadata metadata, Stream<?> actual);
549
550
/**
551
* Fails if the stream is not empty.
552
*/
553
public void isEmpty();
554
555
/**
556
* Fails if the stream is empty.
557
*/
558
public void isNotEmpty();
559
560
/**
561
* Fails if the stream does not have the given size.
562
* @param expectedSize the expected number of elements
563
*/
564
public void hasSize(int expectedSize);
565
566
/**
567
* Fails if the stream does not contain exactly the given elements.
568
* @param elements the expected elements
569
*/
570
public Ordered containsExactly(Object... elements);
571
572
/**
573
* Fails if the stream does not contain exactly the elements in the given iterable.
574
* @param expected the iterable containing expected elements
575
*/
576
public Ordered containsExactlyElementsIn(Iterable<?> expected);
577
}
578
579
/**
580
* Subject class for making assertions about IntStream values.
581
*/
582
public class IntStreamSubject extends Subject {
583
protected IntStreamSubject(FailureMetadata metadata, IntStream actual);
584
585
public void isEmpty();
586
public void isNotEmpty();
587
public void hasSize(int expectedSize);
588
public Ordered containsExactly(int... elements);
589
public Ordered containsExactlyElementsIn(Iterable<Integer> expected);
590
}
591
592
/**
593
* Subject class for making assertions about LongStream values.
594
*/
595
public class LongStreamSubject extends Subject {
596
protected LongStreamSubject(FailureMetadata metadata, LongStream actual);
597
598
public void isEmpty();
599
public void isNotEmpty();
600
public void hasSize(int expectedSize);
601
public Ordered containsExactly(long... elements);
602
public Ordered containsExactlyElementsIn(Iterable<Long> expected);
603
}
604
605
/**
606
* Interface returned by containsExactly methods to enforce ordering constraints.
607
*/
608
public interface Ordered {
609
/**
610
* Requires that the elements appear in the given order.
611
*/
612
void inOrder();
613
}
614
```