or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced.mdbasic-assertions.mdcollections.mdconditions.mddates-times.mdexceptions.mdindex.mdsoft-assertions.mdstrings.md

soft-assertions.mddocs/

0

# Soft Assertions

1

2

Soft assertions collect multiple assertion failures and report them together instead of failing on the first error, enabling comprehensive validation in a single test.

3

4

## Core Imports

5

6

```java

7

import static org.assertj.core.api.Assertions.*;

8

import org.assertj.core.api.SoftAssertions;

9

import org.assertj.core.api.AutoCloseableSoftAssertions;

10

import org.assertj.core.api.junit.jupiter.SoftAssertionsExtension;

11

import org.junit.jupiter.api.extension.ExtendWith;

12

```

13

14

## Capabilities

15

16

### Basic Soft Assertions

17

18

Standard soft assertions that collect errors and report them all at once.

19

20

```java { .api }

21

class SoftAssertions {

22

// Constructor

23

SoftAssertions()

24

25

// All standard assertThat methods available

26

BooleanAssert assertThat(boolean actual)

27

IntegerAssert assertThat(int actual)

28

StringAssert assertThat(String actual)

29

ObjectAssert<T> assertThat(T actual)

30

ListAssert<T> assertThat(List<T> actual)

31

// ... all other assertThat overloads

32

33

// Soft assertion control

34

void assertAll()

35

List<AssertionError> assertionErrorsCollected()

36

boolean hasErrors()

37

boolean wasSuccess()

38

39

// Error message customization

40

SoftAssertions describedAs(String description)

41

SoftAssertions as(String description)

42

}

43

```

44

45

Usage examples:

46

```java

47

// Basic soft assertions usage

48

SoftAssertions softly = new SoftAssertions();

49

50

User user = getUser();

51

softly.assertThat(user.getName()).isNotNull();

52

softly.assertThat(user.getAge()).isPositive();

53

softly.assertThat(user.getEmail()).contains("@");

54

softly.assertThat(user.getRole()).isEqualTo(Role.ADMIN);

55

56

// This will throw AssertionError with ALL failures

57

softly.assertAll();

58

59

// Check if there were any errors without throwing

60

if (softly.hasErrors()) {

61

List<AssertionError> errors = softly.assertionErrorsCollected();

62

// Handle errors as needed

63

}

64

```

65

66

### Auto-Closeable Soft Assertions

67

68

Soft assertions that automatically call `assertAll()` when used in try-with-resources.

69

70

```java { .api }

71

class AutoCloseableSoftAssertions extends SoftAssertions implements AutoCloseable {

72

// Constructor

73

AutoCloseableSoftAssertions()

74

75

// AutoCloseable implementation

76

void close()

77

78

// Inherits all SoftAssertions methods

79

// Automatically calls assertAll() on close

80

}

81

```

82

83

Usage examples:

84

```java

85

// Try-with-resources automatically calls assertAll()

86

try (AutoCloseableSoftAssertions softly = new AutoCloseableSoftAssertions()) {

87

softly.assertThat(name).isNotBlank();

88

softly.assertThat(age).isBetween(18, 65);

89

softly.assertThat(email).matches("\\w+@\\w+\\.\\w+");

90

// assertAll() called automatically when exiting try block

91

}

92

93

// Validation method using auto-closeable soft assertions

94

public void validatePerson(Person person) {

95

try (AutoCloseableSoftAssertions softly = new AutoCloseableSoftAssertions()) {

96

softly.assertThat(person).isNotNull();

97

softly.assertThat(person.getName()).isNotEmpty();

98

softly.assertThat(person.getAge()).isGreaterThan(0);

99

} // assertAll() called here

100

}

101

```

102

103

### BDD Style Soft Assertions

104

105

Behavior-driven development style soft assertions using `then()` instead of `assertThat()`.

106

107

```java { .api }

108

class BDDSoftAssertions {

109

// Constructor

110

BDDSoftAssertions()

111

112

// BDD-style assertion methods (then instead of assertThat)

113

BooleanAssert then(boolean actual)

114

IntegerAssert then(int actual)

115

StringAssert then(String actual)

116

ObjectAssert<T> then(T actual)

117

ListAssert<T> then(List<T> actual)

118

// ... all other then() overloads

119

120

// Control methods

121

void assertAll()

122

List<AssertionError> assertionErrorsCollected()

123

}

124

125

class AutoCloseableBDDSoftAssertions extends BDDSoftAssertions implements AutoCloseable {

126

// Constructor

127

AutoCloseableBDDSoftAssertions()

128

129

// AutoCloseable implementation

130

void close()

131

}

132

```

133

134

Usage examples:

135

```java

136

// BDD-style soft assertions

137

BDDSoftAssertions softly = new BDDSoftAssertions();

138

139

// Given

140

Order order = createTestOrder();

141

142

// When

143

ProcessResult result = orderProcessor.process(order);

144

145

// Then

146

softly.then(result.isSuccess()).isTrue();

147

softly.then(result.getOrderId()).isNotNull();

148

softly.then(result.getTotal()).isGreaterThan(BigDecimal.ZERO);

149

softly.assertAll();

150

151

// Auto-closeable BDD style

152

try (AutoCloseableBDDSoftAssertions softly = new AutoCloseableBDDSoftAssertions()) {

153

softly.then(order.getItems()).isNotEmpty();

154

softly.then(order.getCustomer()).isNotNull();

155

softly.then(order.getStatus()).isEqualTo(OrderStatus.PENDING);

156

}

157

```

158

159

### JUnit 4 Integration

160

161

Soft assertions integrated with JUnit 4 using rules.

162

163

```java { .api }

164

class JUnitSoftAssertions extends SoftAssertions {

165

// JUnit 4 Rule support

166

static JUnitSoftAssertions assertSoftly()

167

}

168

169

class JUnitBDDSoftAssertions extends BDDSoftAssertions {

170

// JUnit 4 BDD Rule support

171

static JUnitBDDSoftAssertions assertSoftly()

172

}

173

```

174

175

Usage examples:

176

```java

177

// JUnit 4 with Rule (not commonly used in modern code)

178

public class MyTest {

179

@Rule

180

public final JUnitSoftAssertions softly = new JUnitSoftAssertions();

181

182

@Test

183

public void testValidation() {

184

softly.assertThat(value1).isPositive();

185

softly.assertThat(value2).isNotNull();

186

// assertAll() called automatically by rule

187

}

188

}

189

```

190

191

### JUnit 5 Integration

192

193

Modern JUnit 5 integration with extensions and parameter injection.

194

195

```java { .api }

196

class JUnitJupiterSoftAssertions extends SoftAssertions {

197

// Constructor

198

JUnitJupiterSoftAssertions()

199

}

200

201

class JUnitJupiterBDDSoftAssertions extends BDDSoftAssertions {

202

// Constructor

203

JUnitJupiterBDDSoftAssertions()

204

}

205

206

// Extension for automatic injection

207

class SoftAssertionsExtension implements ParameterResolver {

208

// Provides SoftAssertions instances to test methods

209

}

210

```

211

212

Usage examples:

213

```java

214

// Method 1: Extension with parameter injection

215

@ExtendWith(SoftAssertionsExtension.class)

216

class ValidationTest {

217

218

@Test

219

void shouldValidateUser(SoftAssertions softly) {

220

User user = createTestUser();

221

222

softly.assertThat(user.getName()).isNotBlank();

223

softly.assertThat(user.getEmail()).contains("@");

224

softly.assertThat(user.isActive()).isTrue();

225

226

softly.assertAll();

227

}

228

}

229

230

// Method 2: Manual instantiation

231

class UserTest {

232

233

@Test

234

void shouldValidateUserManually() {

235

JUnitJupiterSoftAssertions softly = new JUnitJupiterSoftAssertions();

236

237

User user = createTestUser();

238

softly.assertThat(user.getName()).startsWith("Test");

239

softly.assertThat(user.getCreatedDate()).isBeforeOrEqualTo(LocalDate.now());

240

241

softly.assertAll();

242

}

243

}

244

```

245

246

### Error Collection and Reporting

247

248

Advanced error handling and custom reporting.

249

250

```java { .api }

251

// Error collection methods

252

List<AssertionError> assertionErrorsCollected()

253

boolean hasErrors()

254

boolean wasSuccess()

255

String errorsAsString()

256

257

// Custom error handling

258

SoftAssertions onError(Consumer<AssertionError> errorHandler)

259

SoftAssertions collectErrors(boolean collect)

260

```

261

262

Usage examples:

263

```java

264

SoftAssertions softly = new SoftAssertions();

265

266

// Collect multiple validation errors

267

softly.assertThat(user.getName()).isNotNull();

268

softly.assertThat(user.getAge()).isBetween(0, 120);

269

softly.assertThat(user.getEmail()).matches(".*@.*\\..*");

270

271

// Check for errors without throwing

272

if (softly.hasErrors()) {

273

List<AssertionError> errors = softly.assertionErrorsCollected();

274

275

// Log each error individually

276

errors.forEach(error -> logger.error("Validation failed: {}", error.getMessage()));

277

278

// Or get all errors as string

279

String allErrors = softly.errorsAsString();

280

throw new ValidationException("Multiple validation errors: " + allErrors);

281

}

282

```

283

284

### Custom Soft Assertion Extensions

285

286

Creating custom soft assertions for domain objects.

287

288

```java { .api }

289

// Extending SoftAssertions for custom types

290

class CustomSoftAssertions extends SoftAssertions {

291

292

public UserAssert assertThat(User actual) {

293

return proxy(UserAssert.class, User.class, actual);

294

}

295

296

public OrderAssert assertThat(Order actual) {

297

return proxy(OrderAssert.class, Order.class, actual);

298

}

299

}

300

```

301

302

Usage examples:

303

```java

304

// Custom domain-specific soft assertions

305

class UserSoftAssertions extends SoftAssertions {

306

307

public UserAssert assertThat(User actual) {

308

return proxy(UserAssert.class, User.class, actual);

309

}

310

}

311

312

class UserAssert extends AbstractObjectAssert<UserAssert, User> {

313

314

public UserAssert(User actual) {

315

super(actual, UserAssert.class);

316

}

317

318

public UserAssert hasValidEmail() {

319

isNotNull();

320

if (!actual.getEmail().contains("@")) {

321

failWithMessage("Expected email to contain @ but was <%s>", actual.getEmail());

322

}

323

return this;

324

}

325

326

public UserAssert isAdult() {

327

isNotNull();

328

if (actual.getAge() < 18) {

329

failWithMessage("Expected user to be adult but age was <%d>", actual.getAge());

330

}

331

return this;

332

}

333

}

334

335

// Usage

336

UserSoftAssertions softly = new UserSoftAssertions();

337

softly.assertThat(user1).hasValidEmail().isAdult();

338

softly.assertThat(user2).hasValidEmail().isAdult();

339

softly.assertAll();

340

```

341

342

### Soft Assertion Best Practices

343

344

Common patterns and best practices for soft assertions.

345

346

```java { .api }

347

// Validation helper methods

348

static void validateUser(User user) {

349

try (AutoCloseableSoftAssertions softly = new AutoCloseableSoftAssertions()) {

350

softly.assertThat(user).isNotNull();

351

softly.assertThat(user.getName()).isNotBlank();

352

softly.assertThat(user.getAge()).isPositive();

353

softly.assertThat(user.getEmail()).contains("@");

354

}

355

}

356

357

// Batch validation

358

static void validateUsers(List<User> users) {

359

try (AutoCloseableSoftAssertions softly = new AutoCloseableSoftAssertions()) {

360

softly.assertThat(users).isNotEmpty();

361

362

for (int i = 0; i < users.size(); i++) {

363

User user = users.get(i);

364

softly.assertThat(user.getName())

365

.as("User[%d] name", i)

366

.isNotBlank();

367

softly.assertThat(user.getEmail())

368

.as("User[%d] email", i)

369

.contains("@");

370

}

371

}

372

}

373

```

374

375

## Types

376

377

```java { .api }

378

// Core soft assertion classes

379

abstract class AbstractSoftAssertions {

380

protected List<AssertionError> errors

381

protected boolean collectErrors

382

383

void assertAll()

384

List<AssertionError> assertionErrorsCollected()

385

}

386

387

class SoftAssertions extends AbstractSoftAssertions {

388

// Standard soft assertions implementation

389

}

390

391

class AutoCloseableSoftAssertions extends SoftAssertions implements AutoCloseable {

392

void close() // calls assertAll()

393

}

394

395

// BDD variants

396

class BDDSoftAssertions extends AbstractSoftAssertions {

397

// BDD-style methods using then() instead of assertThat()

398

}

399

400

class AutoCloseableBDDSoftAssertions extends BDDSoftAssertions implements AutoCloseable {

401

void close()

402

}

403

404

// JUnit integration classes

405

class JUnitSoftAssertions extends SoftAssertions {

406

// JUnit 4 integration

407

}

408

409

class JUnitJupiterSoftAssertions extends SoftAssertions {

410

// JUnit 5 integration

411

}

412

413

// Error handling

414

class AssertionError extends Error {

415

String getMessage()

416

Throwable getCause()

417

}

418

419

// Consumer for error handling

420

interface Consumer<T> {

421

void accept(T t);

422

}

423

```