0
# Advanced Features
1
2
Advanced AssertJ features including filters, groups, atomic types, concurrent types, predicates, streams, file system operations, and specialized utilities.
3
4
## Core Imports
5
6
```java
7
import static org.assertj.core.api.Assertions.*;
8
import java.util.concurrent.atomic.*;
9
import java.util.concurrent.*;
10
import java.util.stream.*;
11
import java.nio.file.*;
12
import java.util.function.*;
13
```
14
15
## Capabilities
16
17
### Assumptions
18
19
Assumptions for conditional test execution, allowing tests to be skipped when certain conditions are not met.
20
21
```java { .api }
22
// AssertJ assumptions for conditional assertions
23
import static org.assertj.core.api.Assumptions.*;
24
25
// JUnit 5 style assumptions for conditional test execution
26
import static org.assertj.core.api.Assumptions.assumeThat;
27
28
// AssertJ assume methods
29
ObjectAssert<T> assumeThat(T actual)
30
BooleanAssert assumeThat(boolean actual)
31
StringAssert assumeThat(String actual)
32
IntegerAssert assumeThat(int actual)
33
ListAssert<T> assumeThat(List<T> actual)
34
35
// Assumption failure handling
36
void assumingThat(boolean assumption, ThrowingCallable executable)
37
void assumingThat(boolean assumption, Runnable executable)
38
```
39
40
Usage examples:
41
```java
42
// Basic assumptions - skip test if assumption fails
43
@Test
44
void testOnlyOnWindows() {
45
assumeThat(System.getProperty("os.name"))
46
.startsWith("Windows");
47
48
// Test code that only runs on Windows
49
assertThat(windowsSpecificFeature()).isTrue();
50
}
51
52
@Test
53
void testWithMinimumJavaVersion() {
54
assumeThat(System.getProperty("java.version"))
55
.satisfies(version -> {
56
String[] parts = version.split("\\.");
57
int major = Integer.parseInt(parts[0]);
58
return major >= 11;
59
});
60
61
// Test code that requires Java 11+
62
assertThat(modernJavaFeature()).isNotNull();
63
}
64
65
// Conditional execution within test
66
@Test
67
void testWithOptionalFeature() {
68
boolean featureEnabled = isFeatureEnabled();
69
70
assumingThat(featureEnabled, () -> {
71
// This code only runs if feature is enabled
72
assertThat(getFeatureResult()).isEqualTo("expected");
73
});
74
75
// This always runs regardless of assumption
76
assertThat(basicFunctionality()).isTrue();
77
}
78
79
// Collection assumptions
80
@Test
81
void testWithNonEmptyList() {
82
List<String> items = getItems();
83
assumeThat(items).isNotEmpty();
84
85
// Test code that requires non-empty list
86
assertThat(processItems(items)).hasSize(items.size());
87
}
88
89
// Numeric assumptions
90
@Test
91
void testWithPositiveValue() {
92
int value = getValue();
93
assumeThat(value).isPositive();
94
95
// Test code that requires positive value
96
assertThat(calculateSquareRoot(value)).isGreaterThan(0);
97
}
98
```
99
100
### Atomic Type Assertions
101
102
Assertions for java.util.concurrent.atomic types ensuring thread-safe value verification.
103
104
```java { .api }
105
// Atomic reference types
106
AtomicReferenceAssert<T> assertThat(AtomicReference<T> actual)
107
AtomicReferenceArrayAssert<T> assertThat(AtomicReferenceArray<T> actual)
108
AtomicReferenceFieldUpdaterAssert<OBJECT, FIELD> assertThat(AtomicReferenceFieldUpdater<OBJECT, FIELD> actual)
109
110
// Atomic numeric types
111
AtomicIntegerAssert assertThat(AtomicInteger actual)
112
AtomicLongAssert assertThat(AtomicLong actual)
113
AtomicBooleanAssert assertThat(AtomicBoolean actual)
114
115
// Atomic array types
116
AtomicIntegerArrayAssert assertThat(AtomicIntegerArray actual)
117
AtomicLongArrayAssert assertThat(AtomicLongArray actual)
118
119
// Atomic field updaters
120
AtomicIntegerFieldUpdaterAssert<OBJECT> assertThat(AtomicIntegerFieldUpdater<OBJECT> actual)
121
AtomicLongFieldUpdaterAssert<OBJECT> assertThat(AtomicLongFieldUpdater<OBJECT> actual)
122
123
// Atomic marked/stamped references
124
AtomicMarkableReferenceAssert<T> assertThat(AtomicMarkableReference<T> actual)
125
AtomicStampedReferenceAssert<T> assertThat(AtomicStampedReference<T> actual)
126
127
// Long adders
128
LongAdderAssert assertThat(LongAdder actual)
129
```
130
131
Usage examples:
132
```java
133
// Atomic references
134
AtomicReference<String> atomicString = new AtomicReference<>("initial");
135
assertThat(atomicString)
136
.hasValue("initial")
137
.doesNotHaveValue("other");
138
139
AtomicInteger counter = new AtomicInteger(42);
140
assertThat(counter)
141
.hasValue(42)
142
.hasPositiveValue()
143
.hasValueBetween(40, 45);
144
145
// Atomic arrays
146
AtomicIntegerArray atomicArray = new AtomicIntegerArray(new int[]{1, 2, 3});
147
assertThat(atomicArray)
148
.hasArray(new int[]{1, 2, 3})
149
.hasSize(3);
150
151
// Atomic markable reference
152
AtomicMarkableReference<String> markableRef = new AtomicMarkableReference<>("value", true);
153
assertThat(markableRef)
154
.hasReference("value")
155
.isMarked();
156
```
157
158
### Concurrent Type Assertions
159
160
Assertions for concurrent programming constructs like futures and completion stages.
161
162
```java { .api }
163
// Future assertions
164
FutureAssert<T> assertThat(Future<T> actual)
165
CompletableFutureAssert<T> assertThat(CompletableFuture<T> actual)
166
CompletionStageAssert<T> assertThat(CompletionStage<T> actual)
167
168
// Future state methods
169
FutureAssert<T> isDone()
170
FutureAssert<T> isNotDone()
171
FutureAssert<T> isCancelled()
172
FutureAssert<T> isNotCancelled()
173
174
// CompletableFuture methods
175
CompletableFutureAssert<T> isCompletedExceptionally()
176
CompletableFutureAssert<T> isNotCompletedExceptionally()
177
CompletableFutureAssert<T> isCompletedWithValue(T expected)
178
CompletableFutureAssert<T> isCompletedWithValueMatching(Predicate<T> predicate)
179
CompletableFutureAssert<T> hasFailed()
180
CompletableFutureAssert<T> hasNotFailed()
181
CompletableFutureAssert<T> hasFailedWithThrowableThat()
182
```
183
184
Usage examples:
185
```java
186
// CompletableFuture assertions
187
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "result");
188
assertThat(future)
189
.isDone()
190
.isNotCancelled()
191
.isCompletedWithValue("result");
192
193
// Exception handling in futures
194
CompletableFuture<String> failedFuture = CompletableFuture.failedFuture(
195
new RuntimeException("Task failed")
196
);
197
assertThat(failedFuture)
198
.isDone()
199
.isCompletedExceptionally()
200
.hasFailedWithThrowableThat()
201
.isInstanceOf(RuntimeException.class)
202
.hasMessage("Task failed");
203
204
// Async testing
205
CompletableFuture<Integer> asyncResult = CompletableFuture.supplyAsync(() -> {
206
// Simulate work
207
return 42;
208
});
209
210
assertThat(asyncResult)
211
.succeedsWithin(Duration.ofSeconds(5))
212
.isEqualTo(42);
213
```
214
215
### Stream Assertions
216
217
Assertions for Java 8+ streams and stream operations.
218
219
```java { .api }
220
// Stream assertions
221
StreamAssert<T> assertThat(Stream<T> actual)
222
IntStreamAssert assertThat(IntStream actual)
223
LongStreamAssert assertThat(LongStream actual)
224
DoubleStreamAssert assertThat(DoubleStream actual)
225
226
// Stream content methods
227
StreamAssert<T> contains(T... values)
228
StreamAssert<T> containsExactly(T... values)
229
StreamAssert<T> containsOnly(T... values)
230
StreamAssert<T> doesNotContain(T... values)
231
StreamAssert<T> hasSize(int expected)
232
StreamAssert<T> isEmpty()
233
StreamAssert<T> isNotEmpty()
234
235
// Stream operations
236
StreamAssert<T> allMatch(Predicate<? super T> predicate)
237
StreamAssert<T> anyMatch(Predicate<? super T> predicate)
238
StreamAssert<T> noneMatch(Predicate<? super T> predicate)
239
```
240
241
Usage examples:
242
```java
243
// Stream content assertions
244
Stream<String> names = Stream.of("Alice", "Bob", "Charlie");
245
assertThat(names)
246
.hasSize(3)
247
.contains("Bob")
248
.allMatch(name -> name.length() > 2);
249
250
// Numeric stream assertions
251
IntStream numbers = IntStream.range(1, 6); // 1,2,3,4,5
252
assertThat(numbers)
253
.containsExactly(1, 2, 3, 4, 5)
254
.allMatch(n -> n > 0)
255
.noneMatch(n -> n > 10);
256
257
// Stream processing assertions
258
Stream<String> processed = Stream.of("apple", "banana", "cherry")
259
.filter(s -> s.length() > 5)
260
.map(String::toUpperCase);
261
262
assertThat(processed)
263
.containsExactly("BANANA", "CHERRY");
264
```
265
266
### Predicate Assertions
267
268
Assertions for functional predicates and their behavior.
269
270
```java { .api }
271
// Predicate assertions
272
PredicateAssert<T> assertThat(Predicate<T> actual)
273
IntPredicateAssert assertThat(IntPredicate actual)
274
LongPredicateAssert assertThat(LongPredicate actual)
275
DoublePredicateAssert assertThat(DoublePredicate actual)
276
277
// Predicate behavior methods
278
PredicateAssert<T> accepts(T... values)
279
PredicateAssert<T> rejects(T... values)
280
PredicateAssert<T> acceptsAll(Iterable<T> values)
281
PredicateAssert<T> rejectsAll(Iterable<T> values)
282
```
283
284
Usage examples:
285
```java
286
// Custom predicates
287
Predicate<String> isLongString = s -> s.length() > 5;
288
assertThat(isLongString)
289
.accepts("Hello World", "Testing")
290
.rejects("Hi", "Test");
291
292
Predicate<Integer> isEven = n -> n % 2 == 0;
293
assertThat(isEven)
294
.accepts(2, 4, 6, 8)
295
.rejects(1, 3, 5, 7);
296
297
// Numeric predicates
298
IntPredicate isPositive = n -> n > 0;
299
assertThat(isPositive)
300
.accepts(1, 2, 100)
301
.rejects(-1, 0, -100);
302
```
303
304
### File System Assertions
305
306
Assertions for file and path operations.
307
308
```java { .api }
309
// File assertions
310
FileAssert assertThat(File actual)
311
PathAssert assertThat(Path actual)
312
InputStreamAssert assertThat(InputStream actual)
313
314
// File existence and type
315
FileAssert exists()
316
FileAssert doesNotExist()
317
FileAssert isFile()
318
FileAssert isDirectory()
319
FileAssert isAbsolute()
320
FileAssert isRelative()
321
FileAssert isExecutable()
322
FileAssert isReadable()
323
FileAssert isWritable()
324
325
// File content
326
FileAssert hasContent(String expected)
327
FileAssert hasContentEqualTo(File expected)
328
FileAssert hasSameContentAs(File expected)
329
FileAssert hasSize(long expected)
330
FileAssert isEmpty()
331
FileAssert isNotEmpty()
332
333
// Path assertions
334
PathAssert exists()
335
PathAssert doesNotExist()
336
PathAssert isAbsolute()
337
PathAssert isRelative()
338
PathAssert hasParent(Path expected)
339
PathAssert hasFileName(String expected)
340
PathAssert hasExtension(String expected)
341
```
342
343
Usage examples:
344
```java
345
// File assertions
346
File configFile = new File("application.properties");
347
assertThat(configFile)
348
.exists()
349
.isFile()
350
.isReadable()
351
.hasContent("server.port=8080");
352
353
File dataDir = new File("data");
354
assertThat(dataDir)
355
.exists()
356
.isDirectory()
357
.isWritable();
358
359
// Path assertions
360
Path logFile = Paths.get("logs", "application.log");
361
assertThat(logFile)
362
.hasFileName("application.log")
363
.hasExtension("log")
364
.hasParent(Paths.get("logs"));
365
366
// InputStream assertions
367
InputStream inputStream = new ByteArrayInputStream("test content".getBytes());
368
assertThat(inputStream)
369
.hasContent("test content");
370
```
371
372
### Network Assertions
373
374
Assertions for network-related types like URI and URL.
375
376
```java { .api }
377
// URI assertions
378
UriAssert assertThat(URI actual)
379
380
// URI component methods
381
UriAssert hasScheme(String expected)
382
UriAssert hasHost(String expected)
383
UriAssert hasPort(int expected)
384
UriAssert hasPath(String expected)
385
UriAssert hasQuery(String expected)
386
UriAssert hasFragment(String expected)
387
UriAssert hasAuthority(String expected)
388
UriAssert hasUserInfo(String expected)
389
390
// URL assertions
391
UrlAssert assertThat(URL actual)
392
393
// URL methods (similar to URI)
394
UrlAssert hasProtocol(String expected)
395
UrlAssert hasHost(String expected)
396
UrlAssert hasPort(int expected)
397
UrlAssert hasPath(String expected)
398
UrlAssert hasQuery(String expected)
399
UrlAssert hasAnchor(String expected)
400
```
401
402
Usage examples:
403
```java
404
// URI assertions
405
URI apiUri = URI.create("https://api.example.com:8080/users?page=1#section");
406
assertThat(apiUri)
407
.hasScheme("https")
408
.hasHost("api.example.com")
409
.hasPort(8080)
410
.hasPath("/users")
411
.hasQuery("page=1")
412
.hasFragment("section");
413
414
// URL assertions
415
URL websiteUrl = new URL("http://www.example.com/page.html");
416
assertThat(websiteUrl)
417
.hasProtocol("http")
418
.hasHost("www.example.com")
419
.hasPath("/page.html");
420
```
421
422
### Filtering and Extraction
423
424
Advanced filtering and value extraction from collections and arrays.
425
426
```java { .api }
427
// Filtering collections and arrays
428
Filters<E> filter(E[] array)
429
Filters<E> filter(Iterable<E> iterable)
430
431
// Filter operations
432
Filters<E> with(String property, Object expectedValue)
433
Filters<E> with(String property)
434
Filters<E> with(Function<E, Object> propertyExtractor, Object expectedValue)
435
Filters<E> with(Condition<E> condition)
436
Filters<E> being(Condition<E> condition)
437
438
// Property extraction
439
ObjectArrayAssert<Object> extracting(String property)
440
ObjectArrayAssert<Tuple> extracting(String... properties)
441
ObjectArrayAssert<Object> extracting(Function<T, Object> extractor)
442
ObjectArrayAssert<Tuple> extracting(Function<T, Object>... extractors)
443
444
// Flat extraction (for nested collections)
445
ListAssert<Object> flatExtracting(String property)
446
ListAssert<Object> flatExtracting(Function<T, ?> extractor)
447
```
448
449
Usage examples:
450
```java
451
// Complex filtering examples
452
List<Person> people = Arrays.asList(
453
new Person("Alice", 30, "Engineer"),
454
new Person("Bob", 25, "Designer"),
455
new Person("Charlie", 35, "Manager"),
456
new Person("Diana", 28, "Engineer")
457
);
458
459
// Property-based filtering
460
assertThat(people)
461
.filteredOn("profession", "Engineer")
462
.extracting("name")
463
.containsExactly("Alice", "Diana");
464
465
// Condition-based filtering
466
assertThat(people)
467
.filteredOn(person -> person.getAge() > 28)
468
.hasSize(2)
469
.extracting("name")
470
.containsOnly("Alice", "Charlie");
471
472
// Multiple property extraction
473
assertThat(people)
474
.extracting("name", "age", "profession")
475
.contains(
476
tuple("Alice", 30, "Engineer"),
477
tuple("Bob", 25, "Designer")
478
);
479
480
// Nested object extraction
481
List<Order> orders = getOrdersWithItems();
482
assertThat(orders)
483
.flatExtracting(Order::getItems)
484
.extracting(Item::getName)
485
.contains("Product A", "Product B");
486
```
487
488
### Groups and Tuples
489
490
Working with grouped data and tuple collections.
491
492
```java { .api }
493
// Group creation
494
static <T> Group<T> group(String name, T... elements)
495
static <T> Group<T> group(T[] elements, String name)
496
497
// Tuple creation and operations
498
static Tuple tuple(Object... values)
499
500
// Tuple extraction
501
TupleAssert assertThat(Tuple actual)
502
503
// Tuple methods
504
TupleAssert contains(Object... expectedValues)
505
TupleAssert containsExactly(Object... expectedValues)
506
```
507
508
Usage examples:
509
```java
510
// Working with tuples
511
List<Person> people = getPeople();
512
assertThat(people)
513
.extracting("firstName", "lastName", "age")
514
.contains(
515
tuple("John", "Doe", 30),
516
tuple("Jane", "Smith", 25)
517
);
518
519
// Custom tuple assertions
520
Tuple personTuple = tuple("Alice", 30, true);
521
assertThat(personTuple)
522
.containsExactly("Alice", 30, true);
523
```
524
525
### Recursive Comparison
526
527
Deep object comparison with customizable comparison strategies and comprehensive configuration options.
528
529
```java { .api }
530
// Recursive comparison entry point
531
RecursiveComparisonAssert<?> usingRecursiveComparison()
532
RecursiveComparisonAssert<?> usingRecursiveComparison(RecursiveComparisonConfiguration configuration)
533
534
// Field filtering and selection
535
RecursiveComparisonAssert<?> ignoringFields(String... fields)
536
RecursiveComparisonAssert<?> ignoringFieldsOfTypes(Class<?>... types)
537
RecursiveComparisonAssert<?> ignoringFieldsMatchingRegexes(String... regexes)
538
RecursiveComparisonAssert<?> comparingOnlyFields(String... fields)
539
RecursiveComparisonAssert<?> comparingOnlyFieldsOfTypes(Class<?>... types)
540
541
// Null value handling
542
RecursiveComparisonAssert<?> ignoringActualNullFields()
543
RecursiveComparisonAssert<?> ignoringExpectedNullFields()
544
RecursiveComparisonAssert<?> ignoringAllNullFields()
545
546
// Type checking and overriding
547
RecursiveComparisonAssert<?> withStrictTypeChecking()
548
RecursiveComparisonAssert<?> ignoringOverriddenEqualsForTypes(Class<?>... types)
549
RecursiveComparisonAssert<?> ignoringOverriddenEqualsForFields(String... fields)
550
RecursiveComparisonAssert<?> ignoringOverriddenEqualsForFieldsMatchingRegexes(String... regexes)
551
552
// Custom comparators
553
RecursiveComparisonAssert<?> withComparatorForType(Comparator<?> comparator, Class<?> type)
554
RecursiveComparisonAssert<?> withComparatorForFields(Comparator<?> comparator, String... fields)
555
RecursiveComparisonAssert<?> withComparatorForFieldsMatchingRegexes(Comparator<?> comparator, String... regexes)
556
557
// Collection element comparison
558
RecursiveComparisonAssert<?> ignoringCollectionOrder()
559
RecursiveComparisonAssert<?> ignoringCollectionOrderInFields(String... fields)
560
RecursiveComparisonAssert<?> ignoringCollectionOrderInFieldsMatchingRegexes(String... regexes)
561
562
// Configuration object
563
class RecursiveComparisonConfiguration {
564
RecursiveComparisonConfiguration ignoreFields(String... fields)
565
RecursiveComparisonConfiguration ignoreFieldsOfTypes(Class<?>... types)
566
RecursiveComparisonConfiguration compareOnlyFields(String... fields)
567
RecursiveComparisonConfiguration withComparatorForType(Comparator<?> comparator, Class<?> type)
568
RecursiveComparisonConfiguration withStrictTypeChecking()
569
RecursiveComparisonConfiguration ignoreCollectionOrder()
570
}
571
```
572
573
Usage examples:
574
```java
575
// Basic recursive comparison
576
Person actualPerson = new Person("John", 30,
577
new Address("123 Main St", "Anytown", "12345"));
578
Person expectedPerson = new Person("John", 30,
579
new Address("123 Main St", "Anytown", "12345"));
580
581
assertThat(actualPerson)
582
.usingRecursiveComparison()
583
.isEqualTo(expectedPerson);
584
585
// Ignore specific fields across all levels
586
assertThat(actualPerson)
587
.usingRecursiveComparison()
588
.ignoringFields("id", "createdDate", "address.lastModified")
589
.isEqualTo(expectedPerson);
590
591
// Ignore fields by type (e.g., all timestamps)
592
assertThat(actualPerson)
593
.usingRecursiveComparison()
594
.ignoringFieldsOfTypes(LocalDateTime.class, Timestamp.class)
595
.isEqualTo(expectedPerson);
596
597
// Ignore fields matching patterns
598
assertThat(actualPerson)
599
.usingRecursiveComparison()
600
.ignoringFieldsMatchingRegexes(".*[Ii]d$", ".*[Dd]ate.*")
601
.isEqualTo(expectedPerson);
602
603
// Compare only specific fields
604
assertThat(actualPerson)
605
.usingRecursiveComparison()
606
.comparingOnlyFields("name", "age", "address.street")
607
.isEqualTo(expectedPerson);
608
609
// Custom comparators for specific types
610
assertThat(actualPerson)
611
.usingRecursiveComparison()
612
.withComparatorForType(String.CASE_INSENSITIVE_ORDER, String.class)
613
.withComparatorForType(BigDecimal::compareTo, BigDecimal.class)
614
.isEqualTo(expectedPerson);
615
616
// Custom comparators for specific fields
617
assertThat(actualPerson)
618
.usingRecursiveComparison()
619
.withComparatorForFields(String.CASE_INSENSITIVE_ORDER, "name", "address.city")
620
.withComparatorForFieldsMatchingRegexes(Double::compareTo, ".*[Pp]rice.*")
621
.isEqualTo(expectedPerson);
622
623
// Handle collections with different orders
624
List<Person> actualPeople = Arrays.asList(
625
new Person("Alice", 30), new Person("Bob", 25)
626
);
627
List<Person> expectedPeople = Arrays.asList(
628
new Person("Bob", 25), new Person("Alice", 30)
629
);
630
631
assertThat(actualPeople)
632
.usingRecursiveComparison()
633
.ignoringCollectionOrder()
634
.isEqualTo(expectedPeople);
635
636
// Strict type checking (prevents comparing Integer with Long)
637
assertThat(actualValue)
638
.usingRecursiveComparison()
639
.withStrictTypeChecking()
640
.isEqualTo(expectedValue);
641
642
// Ignore overridden equals methods for specific types
643
assertThat(actualPerson)
644
.usingRecursiveComparison()
645
.ignoringOverriddenEqualsForTypes(Address.class)
646
.isEqualTo(expectedPerson);
647
648
// Pre-configured recursive comparison
649
RecursiveComparisonConfiguration config = new RecursiveComparisonConfiguration()
650
.ignoreFields("id", "createdAt", "updatedAt")
651
.ignoringFieldsOfTypes(UUID.class)
652
.withComparatorForType(String.CASE_INSENSITIVE_ORDER, String.class)
653
.ignoreCollectionOrder();
654
655
assertThat(actualObject)
656
.usingRecursiveComparison(config)
657
.isEqualTo(expectedObject);
658
659
// Complex nested object comparison
660
Order actualOrder = new Order(
661
"ORD-001",
662
Arrays.asList(
663
new OrderItem("Product A", 2, new BigDecimal("29.99")),
664
new OrderItem("Product B", 1, new BigDecimal("15.50"))
665
),
666
new Customer("John Doe", "john@example.com")
667
);
668
669
Order expectedOrder = new Order(
670
"ORD-001",
671
Arrays.asList(
672
new OrderItem("Product B", 1, new BigDecimal("15.50")),
673
new OrderItem("Product A", 2, new BigDecimal("29.99"))
674
),
675
new Customer("john doe", "john@example.com") // Different case
676
);
677
678
assertThat(actualOrder)
679
.usingRecursiveComparison()
680
.ignoringCollectionOrder()
681
.withComparatorForFields(String.CASE_INSENSITIVE_ORDER, "customer.name")
682
.isEqualTo(expectedOrder);
683
```
684
685
### Framework Integration
686
687
Integration APIs for working with external frameworks and libraries.
688
689
```java { .api }
690
// Mixin interface for assertion methods
691
interface WithAssertions {
692
// Provides access to all static assertion methods
693
// Implement this interface to get assertion methods without static imports
694
}
695
696
// Hamcrest integration
697
MatcherAssert.assertThat(T actual, Matcher<? super T> matcher)
698
699
// Usage in classes
700
class MyTestClass implements WithAssertions {
701
@Test
702
void myTest() {
703
// Can use assertThat without static import
704
assertThat("Hello").startsWith("H");
705
}
706
}
707
```
708
709
Usage examples:
710
```java
711
// WithAssertions mixin - eliminates need for static imports
712
class IntegrationTest implements WithAssertions {
713
714
@Test
715
void testWithoutStaticImports() {
716
// All AssertJ methods available directly
717
assertThat("Hello World")
718
.startsWith("Hello")
719
.endsWith("World")
720
.hasLength(11);
721
722
assertThat(Arrays.asList(1, 2, 3))
723
.hasSize(3)
724
.contains(2)
725
.doesNotContain(4);
726
727
assertThatThrownBy(() -> {
728
throw new IllegalStateException("Error");
729
}).isInstanceOf(IllegalStateException.class);
730
}
731
732
@Test
733
void testComplexAssertions() {
734
List<Person> people = getPeople();
735
736
assertThat(people)
737
.filteredOn(person -> person.getAge() > 18)
738
.extracting("name")
739
.containsOnly("Alice", "Bob", "Charlie");
740
}
741
}
742
743
// Hamcrest integration - use Hamcrest matchers with AssertJ
744
import static org.hamcrest.Matchers.*;
745
import static org.assertj.core.api.MatcherAssert.assertThat;
746
747
@Test
748
void testWithHamcrestMatchers() {
749
String text = "Hello World";
750
751
// Use Hamcrest matchers with AssertJ's MatcherAssert
752
assertThat(text, startsWith("Hello"));
753
assertThat(text, endsWith("World"));
754
assertThat(text, containsString("lo Wo"));
755
756
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
757
assertThat(numbers, hasSize(5));
758
assertThat(numbers, hasItem(3));
759
assertThat(numbers, everyItem(greaterThan(0)));
760
}
761
762
// Custom matchers with Hamcrest
763
public static Matcher<Person> hasAge(int expectedAge) {
764
return new BaseMatcher<Person>() {
765
@Override
766
public boolean matches(Object item) {
767
return item instanceof Person && ((Person) item).getAge() == expectedAge;
768
}
769
770
@Override
771
public void describeTo(Description description) {
772
description.appendText("person with age ").appendValue(expectedAge);
773
}
774
};
775
}
776
777
@Test
778
void testWithCustomMatcher() {
779
Person person = new Person("Alice", 30);
780
assertThat(person, hasAge(30));
781
}
782
783
// Combining AssertJ and Hamcrest
784
@Test
785
void testCombinedApproaches() {
786
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
787
788
// Use AssertJ for fluent assertions
789
org.assertj.core.api.Assertions.assertThat(names)
790
.hasSize(3)
791
.allMatch(name -> name.length() > 2);
792
793
// Use Hamcrest for pattern matching
794
assertThat(names, hasItems("Alice", "Bob"));
795
assertThat(names, everyItem(not(isEmptyString())));
796
}
797
```
798
799
### Extension Points
800
801
Extension interfaces and factories for customizing AssertJ behavior and error handling.
802
803
```java { .api }
804
// Error factories for custom assertion error creation
805
interface AssertionErrorFactory {
806
AssertionError newAssertionError(Description description, Representation representation)
807
}
808
809
interface ErrorMessageFactory {
810
String create(Description description, Representation representation)
811
}
812
813
// Comparison strategy interface for custom comparison logic
814
interface ComparisonStrategy {
815
boolean areEqual(Object actual, Object other)
816
String asText()
817
}
818
819
// Representation interface for custom object formatting
820
interface Representation {
821
String toStringOf(Object object)
822
String unambiguousToStringOf(Object object)
823
}
824
825
// Description builder for assertion messages
826
interface Description {
827
Description appendText(String text)
828
Description appendDescriptionOf(SelfDescribing value)
829
Description appendValue(Object value)
830
Description appendValueList(String start, String separator, String end, Object... values)
831
}
832
833
// Configuration factories
834
static AssertionErrorFactory setAssertionErrorFactory(AssertionErrorFactory factory)
835
static ComparisonStrategy setComparisonStrategy(ComparisonStrategy comparisonStrategy)
836
```
837
838
Usage examples:
839
```java
840
// Custom assertion error factory
841
public class CustomAssertionErrorFactory implements AssertionErrorFactory {
842
@Override
843
public AssertionError newAssertionError(Description description,
844
Representation representation) {
845
String message = description.toString();
846
// Add custom formatting, logging, or context
847
Logger.getLogger("test").error("Assertion failed: " + message);
848
return new AssertionError("[CUSTOM] " + message);
849
}
850
}
851
852
// Register custom error factory globally
853
Assertions.setAssertionErrorFactory(new CustomAssertionErrorFactory());
854
855
@Test
856
void testWithCustomErrorFactory() {
857
// Failures now use custom error factory
858
assertThat("Hello").isEqualTo("World"); // Custom formatted error
859
}
860
861
// Custom comparison strategy for case-insensitive strings
862
public class CaseInsensitiveComparisonStrategy implements ComparisonStrategy {
863
@Override
864
public boolean areEqual(Object actual, Object other) {
865
if (actual instanceof String && other instanceof String) {
866
return ((String) actual).equalsIgnoreCase((String) other);
867
}
868
return Objects.equals(actual, other);
869
}
870
871
@Override
872
public String asText() {
873
return "CaseInsensitiveComparisonStrategy";
874
}
875
}
876
877
// Use custom comparison strategy
878
ComparisonStrategy originalStrategy = Assertions.getComparisionStrategy();
879
try {
880
Assertions.setComparisonStrategy(new CaseInsensitiveComparisonStrategy());
881
882
assertThat("Hello").isEqualTo("HELLO"); // Passes with case-insensitive comparison
883
assertThat(Arrays.asList("Test", "DATA"))
884
.contains("test", "data"); // Case-insensitive collection comparison
885
886
} finally {
887
// Restore original strategy
888
Assertions.setComparisonStrategy(originalStrategy);
889
}
890
891
// Custom representation for domain objects
892
public class PersonRepresentation extends StandardRepresentation {
893
@Override
894
public String toStringOf(Object object) {
895
if (object instanceof Person) {
896
Person p = (Person) object;
897
return String.format("Person{name='%s', age=%d, email='%s'}",
898
p.getName(), p.getAge(), p.getEmail());
899
}
900
return super.toStringOf(object);
901
}
902
}
903
904
// Use custom representation
905
Representation originalRep = Assertions.getRepresentation();
906
try {
907
Assertions.useRepresentation(new PersonRepresentation());
908
909
Person person = new Person("Alice", 30, "alice@example.com");
910
assertThat(person).isNull(); // Error message uses custom representation
911
912
} finally {
913
Assertions.useRepresentation(originalRep);
914
}
915
916
// Custom error message factory
917
public class CustomErrorMessageFactory implements ErrorMessageFactory {
918
@Override
919
public String create(Description description, Representation representation) {
920
String baseMessage = description.toString();
921
922
// Add contextual information
923
Thread currentThread = Thread.currentThread();
924
String threadInfo = String.format(" [Thread: %s, Time: %s]",
925
currentThread.getName(),
926
Instant.now());
927
928
return baseMessage + threadInfo;
929
}
930
}
931
932
// Custom description builder for complex assertions
933
public class DetailedDescription implements Description {
934
private final StringBuilder sb = new StringBuilder();
935
936
@Override
937
public Description appendText(String text) {
938
sb.append(text);
939
return this;
940
}
941
942
@Override
943
public Description appendDescriptionOf(SelfDescribing value) {
944
sb.append(value.toString());
945
return this;
946
}
947
948
@Override
949
public Description appendValue(Object value) {
950
sb.append("'").append(value).append("'");
951
return this;
952
}
953
954
@Override
955
public Description appendValueList(String start, String separator,
956
String end, Object... values) {
957
sb.append(start);
958
for (int i = 0; i < values.length; i++) {
959
if (i > 0) sb.append(separator);
960
appendValue(values[i]);
961
}
962
sb.append(end);
963
return this;
964
}
965
966
@Override
967
public String toString() {
968
return sb.toString();
969
}
970
}
971
972
// Extension point for custom assert classes
973
public class CustomStringAssert extends AbstractStringAssert<CustomStringAssert> {
974
975
public CustomStringAssert(String actual) {
976
super(actual, CustomStringAssert.class);
977
}
978
979
public static CustomStringAssert assertThat(String actual) {
980
return new CustomStringAssert(actual);
981
}
982
983
// Custom assertion method
984
public CustomStringAssert isValidEmail() {
985
isNotNull();
986
if (!actual.contains("@") || !actual.contains(".")) {
987
failWithMessage("Expected <%s> to be a valid email address", actual);
988
}
989
return this;
990
}
991
992
// Custom assertion with detailed error
993
public CustomStringAssert hasValidLength(int min, int max) {
994
isNotNull();
995
int length = actual.length();
996
if (length < min || length > max) {
997
failWithMessage("Expected string length to be between <%d> and <%d> but was <%d>",
998
min, max, length);
999
}
1000
return this;
1001
}
1002
}
1003
1004
// Usage of custom assert class
1005
@Test
1006
void testWithCustomStringAssert() {
1007
CustomStringAssert.assertThat("user@example.com")
1008
.isValidEmail()
1009
.hasValidLength(5, 50)
1010
.startsWith("user");
1011
1012
CustomStringAssert.assertThat("invalid-email")
1013
.isValidEmail(); // Fails with custom message
1014
}
1015
1016
// Global extension configuration
1017
@BeforeAll
1018
static void configureAssertJ() {
1019
// Set custom factories and strategies globally
1020
Assertions.setAssertionErrorFactory(new CustomAssertionErrorFactory());
1021
Assertions.useRepresentation(new PersonRepresentation());
1022
1023
// Configure behavior
1024
Assertions.setAllowExtractingPrivateFields(true);
1025
Assertions.setMaxElementsForPrinting(100);
1026
Assertions.setPrintAssertionsDescription(true);
1027
}
1028
```
1029
1030
### Configuration and Utilities
1031
1032
Global configuration and utility methods.
1033
1034
```java { .api }
1035
// Global configuration methods
1036
static void setAllowExtractingPrivateFields(boolean allowExtractingPrivateFields)
1037
static void setAllowComparingPrivateFields(boolean allowComparingPrivateFields)
1038
static void setExtractBareNamePropertyMethods(boolean extractBareNamePropertyMethods)
1039
static void setLenientDateParsing(boolean lenientDateParsing)
1040
static void setMaxElementsForPrinting(int maxElementsForPrinting)
1041
static void setMaxLengthForSingleLineDescription(int maxLengthForSingleLineDescription)
1042
static void setPrintAssertionsDescription(boolean printAssertionsDescription)
1043
1044
// Representation configuration
1045
static void useDefaultRepresentation()
1046
static void useRepresentation(Representation representation)
1047
1048
// Date parsing configuration
1049
static void useDefaultDateFormatsOnly()
1050
static void registerCustomDateFormat(DateFormat customDateFormat)
1051
static void registerCustomDateFormat(String customDateFormatPattern)
1052
```
1053
1054
Usage examples:
1055
```java
1056
// Configure AssertJ behavior globally
1057
Assertions.setMaxElementsForPrinting(50);
1058
Assertions.setPrintAssertionsDescription(true);
1059
Assertions.setLenientDateParsing(true);
1060
1061
// Custom representation
1062
Assertions.useRepresentation(new StandardRepresentation() {
1063
@Override
1064
protected String toStringOf(Object object) {
1065
if (object instanceof Person) {
1066
Person p = (Person) object;
1067
return String.format("Person[%s, %d]", p.getName(), p.getAge());
1068
}
1069
return super.toStringOf(object);
1070
}
1071
});
1072
```
1073
1074
## Types
1075
1076
```java { .api }
1077
// Atomic reference types
1078
class AtomicReference<V> {
1079
V get()
1080
void set(V newValue)
1081
boolean compareAndSet(V expect, V update)
1082
}
1083
1084
class AtomicInteger extends Number {
1085
int get()
1086
void set(int newValue)
1087
int addAndGet(int delta)
1088
boolean compareAndSet(int expect, int update)
1089
}
1090
1091
// Concurrent types
1092
interface Future<V> {
1093
boolean isDone()
1094
boolean isCancelled()
1095
V get() throws InterruptedException, ExecutionException
1096
}
1097
1098
class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
1099
boolean isCompletedExceptionally()
1100
T join()
1101
static <U> CompletableFuture<U> completedFuture(U value)
1102
static <U> CompletableFuture<U> failedFuture(Throwable ex)
1103
}
1104
1105
// Stream types
1106
interface Stream<T> extends BaseStream<T, Stream<T>> {
1107
Stream<T> filter(Predicate<? super T> predicate)
1108
<R> Stream<R> map(Function<? super T, ? extends R> mapper)
1109
boolean allMatch(Predicate<? super T> predicate)
1110
boolean anyMatch(Predicate<? super T> predicate)
1111
boolean noneMatch(Predicate<? super T> predicate)
1112
}
1113
1114
// File system types
1115
class File {
1116
boolean exists()
1117
boolean isFile()
1118
boolean isDirectory()
1119
long length()
1120
boolean canRead()
1121
boolean canWrite()
1122
boolean canExecute()
1123
}
1124
1125
interface Path {
1126
boolean isAbsolute()
1127
Path getParent()
1128
Path getFileName()
1129
String toString()
1130
}
1131
1132
// Filter and extraction types
1133
class Filters<E> {
1134
Filters<E> with(String property, Object expectedValue)
1135
Filters<E> with(Condition<E> condition)
1136
}
1137
1138
class Tuple {
1139
static Tuple tuple(Object... values)
1140
Object[] toArray()
1141
List<Object> toList()
1142
}
1143
1144
// Functional interfaces
1145
interface Predicate<T> {
1146
boolean test(T t);
1147
}
1148
1149
interface Function<T, R> {
1150
R apply(T t);
1151
}
1152
1153
interface Consumer<T> {
1154
void accept(T t);
1155
}
1156
1157
// Comparison types
1158
interface Comparator<T> {
1159
int compare(T o1, T o2);
1160
}
1161
1162
class RecursiveComparisonConfiguration {
1163
RecursiveComparisonConfiguration ignoreFields(String... fields)
1164
RecursiveComparisonConfiguration ignoreFieldsOfTypes(Class<?>... types)
1165
RecursiveComparisonConfiguration ignoreFieldsMatchingRegexes(String... regexes)
1166
RecursiveComparisonConfiguration compareOnlyFields(String... fields)
1167
RecursiveComparisonConfiguration compareOnlyFieldsOfTypes(Class<?>... types)
1168
RecursiveComparisonConfiguration ignoringActualNullFields()
1169
RecursiveComparisonConfiguration ignoringExpectedNullFields()
1170
RecursiveComparisonConfiguration ignoringAllNullFields()
1171
RecursiveComparisonConfiguration withStrictTypeChecking()
1172
RecursiveComparisonConfiguration ignoringOverriddenEqualsForTypes(Class<?>... types)
1173
RecursiveComparisonConfiguration ignoringOverriddenEqualsForFields(String... fields)
1174
RecursiveComparisonConfiguration withComparatorForType(Comparator<?> comparator, Class<?> type)
1175
RecursiveComparisonConfiguration withComparatorForFields(Comparator<?> comparator, String... fields)
1176
RecursiveComparisonConfiguration ignoreCollectionOrder()
1177
RecursiveComparisonConfiguration ignoringCollectionOrderInFields(String... fields)
1178
}
1179
1180
// Extension interfaces
1181
interface AssertionErrorFactory {
1182
AssertionError newAssertionError(Description description, Representation representation)
1183
}
1184
1185
interface ErrorMessageFactory {
1186
String create(Description description, Representation representation)
1187
}
1188
1189
interface ComparisonStrategy {
1190
boolean areEqual(Object actual, Object other)
1191
String asText()
1192
}
1193
1194
interface Representation {
1195
String toStringOf(Object object)
1196
String unambiguousToStringOf(Object object)
1197
}
1198
1199
interface Description {
1200
Description appendText(String text)
1201
Description appendDescriptionOf(SelfDescribing value)
1202
Description appendValue(Object value)
1203
Description appendValueList(String start, String separator, String end, Object... values)
1204
}
1205
1206
// Assumption types
1207
interface Assumptions {
1208
static <T> ObjectAssert<T> assumeThat(T actual)
1209
static BooleanAssert assumeThat(boolean actual)
1210
static StringAssert assumeThat(String actual)
1211
static IntegerAssert assumeThat(int actual)
1212
static <T> ListAssert<T> assumeThat(List<T> actual)
1213
static void assumingThat(boolean assumption, ThrowingCallable executable)
1214
static void assumingThat(boolean assumption, Runnable executable)
1215
}
1216
1217
// Integration types
1218
interface WithAssertions {
1219
// Mixin interface providing access to all assertion methods
1220
// Classes implementing this can use assertThat methods without static imports
1221
}
1222
1223
class MatcherAssert {
1224
static <T> void assertThat(T actual, Matcher<? super T> matcher)
1225
}
1226
```