Using try-catch blocks combined with fail() to test for the presence or absence of exceptions is an anti-pattern.
Modern assertion libraries have made the clunky try-fail-catch pattern obsolete by introducing cleaner alternatives. For example,
starting with JUnit 5, JUnit Jupiter provides assertThrows and assertDoesNotThrow. AssertJ offers similar methods.
Using try-catch with fail() for the same purpose adds boilerplate, makes the test intent less explicit, and is harder to
maintain. Dedicated exception assertions also make it straightforward to keep asserting on the exception when one is expected.
Replace try-catch blocks that rely on fail() to verify exception behavior with dedicated exception assertions from your
testing library:
assertDoesNotThrow and assertThrows.assertThatCode, assertThatThrownBy, and assertThatExceptionOfType.
@Test
void testNoExceptionThrown() {
try {
userService.registerUser(validUser);
} catch (ValidationException e) {
fail("Should not have thrown any exception");
}
}
@Test
void testNoExceptionWithAssertion() {
assertDoesNotThrow(() -> userService.registerUser(validUser));
}
@Test
void testExceptionIsThrown() {
try {
userService.registerUser(invalidUser);
fail("Expected ValidationException to be thrown");
} catch (ValidationException e) {
// Test passes, but code is verbose
assertEquals("Invalid email", e.getMessage());
}
}
@Test
void testExceptionWithAssertion() {
ValidationException exception = assertThrows(ValidationException.class, () -> userService.registerUser(invalidUser));
assertEquals("Invalid email", exception.getMessage());
}
@Test
void testNoExceptionThrown() {
try {
userService.registerUser(validUser);
} catch (ValidationException e) {
fail("Should not have thrown any exception");
}
}
@Test
void testNoExceptionWithAssertion() {
assertThatCode(() -> userService.registerUser(validUser)).doesNotThrowAnyException();
}
@Test
void testExceptionIsThrown() {
try {
userService.registerUser(invalidUser);
fail("Expected ValidationException to be thrown");
} catch (ValidationException e) {
assertThat(e).hasMessage("Invalid email");
}
}
@Test
void testExceptionWithAssertion() {
assertThatThrownBy(() -> userService.registerUser(invalidUser))
.isInstanceOf(ValidationException.class)
.hasMessage("Invalid email");
}