# Replace JUnit ExpectedException with assertThrows
# Description
The ExpectedException.none()
(opens new window) rule is deprecated since JUnit 4.13.
The recommended alternative is to use assertThrows()
(opens new window).
This makes JUnit tests easier to understand and prevents scenarios where some parts of the test code are unreachable.
The goal of this rule is to replace expectedException.expect()
with assertThrows
.
Additionally, new assertions are added for each invocation of expectMessage()
(opens new window) and expectCause()
(opens new window).
See more examples in the section below.
Requirements
This rule requires one of the following libraries to be present:
- junit:junit:4.13
- org.junit.jupiter:junit-jupiter-api:5.0.0
# Benefits
Improves the tests readability. Helps migrating to JUnit 5.
# Tags
# Code Changes
# Testing the Exception Type
Pre
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Test
public void expectIOException() throws IOException {
expectedException.expect(IOException.class);
throwsIOException("Throw an IOException");
}
Post
@Test
public void expectIOException() {
assertThrows(IOException.class, () -> throwsIOException("Throw an IOException"));
}
# Testing the Exception Message
Pre
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Test
public void expectIOException() throws IOException {
expectedException.expect(IOException.class);
expectedException.expectMessage("IO");
throwsIOException("Throw an IOException");
}
Post
@Test
public void expectIOException() {
IOException exception = assertThrows(IOException.class,
() -> throwsIOException("Throw an IOException"));
assertTrue(exception.getMessage().contains("IO"));
}
# Using Hamcrest Matchers
Pre
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Test
public void expectIOException() throws IOException {
expectedException.expect(IOException.class);
expectedException.expectMessage(containsString("IO"));
throwsIOException("Throw an IOException");
}
Post
@Test
public void expectIOException() {
IOException exception = assertThrows(IOException.class,
() -> throwsIOException("Throw an IOException"));
assertThat(exception.getMessage(), containsString("IO"));
}
# Testing Expected Cause
Pre
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Test
public void testingExceptionCause() throws IOException {
Matcher<Throwable> isNotFileNotFoundException = not(is(new FileNotFoundException()));
expectedException.expect(IOException.class);
expectedException.expectCause(isNotFileNotFoundException);
throwIOException();
}
Post
@Test
public void testingExceptionCause() {
Matcher<Throwable> isNotFileNotFoundException = not(is(new FileNotFoundException()));
IOException exception = assertThrows(IOException.class, () -> throwIOException());
assertThat(exception.getCause(), isNotFileNotFoundException);
}
# Throwing Runtime Exceptions Explicitly
Pre
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Test
public void explicitlyThrowingRuntimeException() {
expectedException.expect(NullPointerException.class);
throw new NullPointerException();
}
Post
@Test
public void explicitlyThrowingRuntimeException() {
assertThrows(NullPointerException.class, () -> {
throw new NullPointerException();
});
}
# Limitations
- Expected Runtime exceptions are not supported unless it can be explicitly derived that the last statements throws the expected exception.
@Test
public void expectingRuntimeException() {
expectedException.expect(NullPointerException.class);
User user = userRepository.findById("10");
setName("John")
save(user);
throwRuntimeException();
}
🛠️ Auto-refactor Available
You can auto-refactor this with jSparrow.
Drop this button to your Eclipse IDE workspace to install jSparrow for free:
Need help? Check out our installation guide.
# Properties
Property | Value |
---|---|
Rule ID | ReplaceJUnitExpectedException |
First seen in jSparrow version | 3.24.0 |
Minimum Java version | 8 |
Remediation cost | 5 min |