0
# Conditions
1
2
Custom conditions and condition combinators for reusable and composable assertions that can be applied to any object type.
3
4
## Core Imports
5
6
```java
7
import static org.assertj.core.api.Assertions.*;
8
import org.assertj.core.api.Condition;
9
```
10
11
## Capabilities
12
13
### Creating Custom Conditions
14
15
Define reusable conditions for complex validation logic.
16
17
```java { .api }
18
// Condition interface
19
interface Condition<T> {
20
boolean matches(T value)
21
String description()
22
}
23
24
// Creating conditions
25
static <T> Condition<T> condition(Predicate<T> predicate, String description)
26
static <T> Condition<T> condition(Predicate<T> predicate, String description, Object... args)
27
28
// Constructor-based condition creation
29
class Condition<T> {
30
Condition(Predicate<T> predicate, String description)
31
Condition(String description, Predicate<T> predicate) // deprecated order
32
}
33
```
34
35
Usage examples:
36
```java
37
// Simple custom conditions
38
Condition<String> notBlank = new Condition<>(
39
s -> s != null && !s.trim().isEmpty(),
40
"not blank"
41
);
42
43
Condition<Integer> positive = new Condition<>(
44
n -> n > 0,
45
"positive number"
46
);
47
48
Condition<User> adult = new Condition<>(
49
user -> user.getAge() >= 18,
50
"adult user"
51
);
52
53
// Using conditions in assertions
54
assertThat("Hello").is(notBlank);
55
assertThat(42).satisfies(positive);
56
assertThat(user).has(adult);
57
```
58
59
### Condition Combinators
60
61
Combine multiple conditions using logical operators.
62
63
```java { .api }
64
// Logical combinators
65
static <T> Condition<T> allOf(Condition<? super T>... conditions)
66
static <T> Condition<T> allOf(Iterable<? extends Condition<? super T>> conditions)
67
static <T> Condition<T> anyOf(Condition<? super T>... conditions)
68
static <T> Condition<T> anyOf(Iterable<? extends Condition<? super T>> conditions)
69
static <T> Condition<T> not(Condition<? super T> condition)
70
71
// Condition chaining methods
72
Condition<T> and(Condition<? super T> other)
73
Condition<T> or(Condition<? super T> other)
74
```
75
76
Usage examples:
77
```java
78
// Define individual conditions
79
Condition<String> notNull = new Condition<>(Objects::nonNull, "not null");
80
Condition<String> notEmpty = new Condition<>(s -> !s.isEmpty(), "not empty");
81
Condition<String> hasLength = new Condition<>(s -> s.length() > 5, "length > 5");
82
83
// Combine conditions
84
Condition<String> validString = allOf(notNull, notEmpty, hasLength);
85
Condition<String> someValid = anyOf(notEmpty, hasLength);
86
Condition<String> invalid = not(validString);
87
88
// Use combined conditions
89
assertThat("Hello World").is(validString);
90
assertThat("Hi").is(someValid);
91
assertThat("").is(invalid);
92
93
// Chaining approach
94
Condition<Integer> validAge = positive.and(
95
new Condition<>(age -> age <= 150, "reasonable age")
96
);
97
98
assertThat(25).satisfies(validAge);
99
```
100
101
### Using Conditions in Assertions
102
103
Apply conditions to assertions using various methods.
104
105
```java { .api }
106
// Condition assertion methods
107
ObjectAssert<T> is(Condition<? super T> condition)
108
ObjectAssert<T> isNot(Condition<? super T> condition)
109
ObjectAssert<T> has(Condition<? super T> condition)
110
ObjectAssert<T> doesNotHave(Condition<? super T> condition)
111
ObjectAssert<T> satisfies(Condition<? super T> condition)
112
ObjectAssert<T> satisfiesAnyOf(Condition<? super T>... conditions)
113
114
// Collection condition methods
115
IterableAssert<T> are(Condition<? super T> condition)
116
IterableAssert<T> areNot(Condition<? super T> condition)
117
IterableAssert<T> have(Condition<? super T> condition)
118
IterableAssert<T> doNotHave(Condition<? super T> condition)
119
IterableAssert<T> areAtLeast(int times, Condition<? super T> condition)
120
IterableAssert<T> areAtMost(int times, Condition<? super T> condition)
121
IterableAssert<T> areExactly(int times, Condition<? super T> condition)
122
IterableAssert<T> haveAtLeast(int times, Condition<? super T> condition)
123
IterableAssert<T> haveAtMost(int times, Condition<? super T> condition)
124
IterableAssert<T> haveExactly(int times, Condition<? super T> condition)
125
```
126
127
Usage examples:
128
```java
129
// Single object conditions
130
User user = new User("Alice", 30, "alice@domain.com");
131
132
assertThat(user).is(adult);
133
assertThat(user).has(validEmail);
134
assertThat(user).satisfies(allOf(adult, validEmail));
135
136
// Collection conditions
137
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
138
139
assertThat(numbers).are(positive);
140
assertThat(numbers).haveAtLeast(3, new Condition<>(n -> n > 2, "> 2"));
141
assertThat(numbers).areExactly(2, new Condition<>(n -> n % 2 == 0, "even"));
142
143
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
144
Condition<String> shortName = new Condition<>(s -> s.length() <= 5, "short name");
145
146
assertThat(names).areAtMost(2, shortName);
147
```
148
149
### Predefined Conditions
150
151
Common conditions provided by AssertJ.
152
153
```java { .api }
154
// Predefined condition factories
155
static <T> Condition<T> matching(Predicate<T> predicate, String description)
156
static <T> Condition<T> not(Condition<? super T> condition)
157
158
// Collection-specific conditions
159
static <T> Condition<Iterable<? extends T>> hasSize(int expectedSize)
160
static <T> Condition<T[]> hasSize(int expectedSize)
161
```
162
163
Usage examples:
164
```java
165
// Using predefined conditions
166
List<String> items = Arrays.asList("one", "two", "three");
167
168
assertThat(items).has(hasSize(3));
169
assertThat(new String[]{"a", "b"}).has(hasSize(2));
170
```
171
172
### Advanced Condition Patterns
173
174
Complex condition scenarios and patterns.
175
176
```java { .api }
177
// Condition composition
178
static <T> Condition<T> describedAs(String description, Condition<T> condition)
179
180
// Verbose conditions with detailed error messages
181
class VerboseCondition<T> extends Condition<T> {
182
VerboseCondition(Predicate<T> predicate, String description)
183
}
184
```
185
186
Usage examples:
187
```java
188
// Domain-specific conditions
189
Condition<Order> validOrder = new Condition<>(order ->
190
order != null &&
191
order.getCustomer() != null &&
192
!order.getItems().isEmpty() &&
193
order.getTotal().compareTo(BigDecimal.ZERO) > 0,
194
"valid order"
195
);
196
197
Condition<Product> inStock = new Condition<>(product ->
198
product.getQuantity() > 0,
199
"in stock"
200
);
201
202
Condition<Product> affordable = new Condition<>(product ->
203
product.getPrice().compareTo(new BigDecimal("100")) <= 0,
204
"affordable (≤ $100)"
205
);
206
207
// Complex business rules
208
Condition<Order> eligibleForDiscount = allOf(
209
validOrder,
210
new Condition<>(order -> order.getTotal().compareTo(new BigDecimal("50")) >= 0, "minimum $50"),
211
new Condition<>(order -> order.getCustomer().isPremium(), "premium customer")
212
);
213
214
assertThat(order).satisfies(eligibleForDiscount);
215
216
// Collection with complex conditions
217
List<Product> products = getProducts();
218
219
assertThat(products)
220
.haveAtLeast(5, inStock)
221
.haveAtMost(10, affordable)
222
.areNot(new Condition<>(Product::isDiscontinued, "discontinued"));
223
```
224
225
### Condition Error Messages
226
227
Customizing condition error messages and descriptions.
228
229
```java { .api }
230
// Custom error message formatting
231
Condition<T> describedAs(String description)
232
Condition<T> as(String description)
233
234
// Error message with parameters
235
static <T> Condition<T> condition(Predicate<T> predicate, String description, Object... args)
236
```
237
238
Usage examples:
239
```java
240
// Descriptive conditions with context
241
Condition<String> validUsername = new Condition<>(
242
username -> username.matches("[a-zA-Z0-9_]{3,20}"),
243
"valid username (3-20 alphanumeric characters or underscore)"
244
);
245
246
Condition<Integer> inRange = new Condition<>(
247
value -> value >= 1 && value <= 100,
248
"in range [1, 100]"
249
);
250
251
// Parameterized descriptions
252
Condition<String> hasMinLength(int minLength) {
253
return new Condition<>(
254
s -> s.length() >= minLength,
255
"has minimum length of %d characters",
256
minLength
257
);
258
}
259
260
// Usage with better error messages
261
assertThat("ab").satisfies(hasMinLength(3));
262
// Error: Expecting <"ab"> to satisfy: <has minimum length of 3 characters>
263
264
assertThat("user!").satisfies(validUsername);
265
// Error: Expecting <"user!"> to satisfy: <valid username (3-20 alphanumeric characters or underscore)>
266
```
267
268
### Condition Utilities and Helpers
269
270
Utility methods for working with conditions.
271
272
```java { .api }
273
// Condition testing
274
boolean matches(T value)
275
String description()
276
277
// Condition factories for common scenarios
278
static <T> Condition<T> anyOf(Collection<? extends Condition<? super T>> conditions)
279
static <T> Condition<T> allOf(Collection<? extends Condition<? super T>> conditions)
280
```
281
282
Usage examples:
283
```java
284
// Testing conditions directly
285
Condition<String> emailFormat = new Condition<>(
286
email -> email.contains("@") && email.contains("."),
287
"valid email format"
288
);
289
290
String testEmail = "user@domain.com";
291
boolean isValid = emailFormat.matches(testEmail);
292
System.out.println("Email valid: " + isValid);
293
System.out.println("Condition: " + emailFormat.description());
294
295
// Building condition collections
296
List<Condition<User>> userValidations = Arrays.asList(
297
new Condition<>(u -> u.getName() != null, "has name"),
298
new Condition<>(u -> u.getAge() >= 0, "non-negative age"),
299
new Condition<>(u -> u.getEmail().contains("@"), "valid email")
300
);
301
302
Condition<User> allUserValidations = allOf(userValidations);
303
assertThat(user).satisfies(allUserValidations);
304
305
// Conditional validation based on type
306
Condition<Object> typeSpecific = new Condition<>(obj -> {
307
if (obj instanceof String) {
308
return !((String) obj).isEmpty();
309
} else if (obj instanceof Number) {
310
return ((Number) obj).doubleValue() >= 0;
311
}
312
return true;
313
}, "type-specific validation");
314
```
315
316
## Types
317
318
```java { .api }
319
// Core condition interface
320
interface Condition<T> {
321
boolean matches(T value);
322
String description();
323
324
// Default combination methods
325
default Condition<T> and(Condition<? super T> other) {
326
return allOf(this, other);
327
}
328
329
default Condition<T> or(Condition<? super T> other) {
330
return anyOf(this, other);
331
}
332
}
333
334
// Predicate interface for condition logic
335
interface Predicate<T> {
336
boolean test(T t);
337
338
// Default combination methods
339
default Predicate<T> and(Predicate<? super T> other);
340
default Predicate<T> or(Predicate<? super T> other);
341
default Predicate<T> negate();
342
}
343
344
// Condition implementation classes
345
abstract class Join<T> extends Condition<T> {
346
// Base class for condition combinators
347
}
348
349
class AllOf<T> extends Join<T> {
350
// AND combination of conditions
351
}
352
353
class AnyOf<T> extends Join<T> {
354
// OR combination of conditions
355
}
356
357
class Not<T> extends Condition<T> {
358
// Negation of a condition
359
}
360
361
class VerboseCondition<T> extends Condition<T> {
362
// Condition with enhanced error reporting
363
}
364
```