Catch and verify exceptions in a single line of code
This is continuation of famous catch-exception library created by Rod Woo.
This library catches exceptions in a single line of code and makes them available for further analysis.
The most basic usage is:
import static com.googlecode.catchexception.CatchException.*;
// given: an empty list
List myList = new ArrayList();
// when: we try to get the first element of the list
// then: catch the exception if any is thrown
catchException(() -> myList.get(1));
// then: we expect an IndexOutOfBoundsException
assert caughtException() instanceof IndexOutOfBoundsException;
The last both lines of code can be combined in a single line of code if you like:
verifyException(myList, IndexOutOfBoundsException.class).get(1);
More information about the usage you find in the Javadoc documentation.
If you prefer a BDD-like approach, you can use BDDCatchException for another code style:
import static com.googlecode.catchexception.apis.BDDCatchException.*;
// given: an empty list
List myList = new ArrayList();
// when: we try to get the first element of the list
when(() -> myList.get(1));
// then: we expect an IndexOutOfBoundsException
then(caughtException())
.isInstanceOf(IndexOutOfBoundsException.class)
.hasMessage("Index: 1, Size: 0")
.hasNoCause();
The assertions used here are part of AssertJ.
If you prefer Hamcrest matchers to express assertions, you can use CatchExceptionHamcrestMatchers with the following code style:
import static com.googlecode.catchexception.CatchException.*;
import static com.googlecode.catchexception.apis.CatchExceptionHamcrestMatchers.*;
// given: an empty list
List myList = new ArrayList();
// when: we try to get the first element of the list
catchException(myList).get(1);
// then: we expect an IndexOutOfBoundsException with message "Index: 1, Size: 0"
assertThat(caughtException(),
allOf(
instanceOf(equalTo(IndexOutOfBoundsException.class)),
CatchExceptionHamcrestMatchers.hasMessage("Index: 1, Size: 0"),
CatchExceptionHamcrestMatchers.hasNoCause()
)
);
Catch-exception supports exceptions that are thrown by constructors.
verifyException(() -> new Thing("baddata"));
Thanks to the community for the example.
If you want to catch both throwables and exceptions have a look at the catch-throwable
packages in javadoc. They provide the same API as the catch-exception
packages but they belong to a different maven module.
If you want to handle expected exceptions, the documentation of catch-exception names some general reasons to prefer catch-exception in comparison to mechanisms that are provided by testing frameworks.
But some reasons that are specific to JUnit4 are outlined only here.
If you want to combine the JUnit4's rules ExpectedException and ErrorCollector you will find out: this won't work.
Catch-exception instead can be easily combined with the error collecting rule:
@Rule
public ErrorCollector collector = new ErrorCollector();
@Test
public void testErrorCollectorWithExpectedException() {
// collect first error
collector.checkThat("a", equalTo("b"));
// collect second error
catchException(() -> new ArrayList().get(1));
collector.checkThat(caughtException(), instanceOf(IllegalArgumentException.class));
// collect third error
collector.checkThat(1, equalTo(2));
}
Sometimes you want to test for an optional exception in a parameterized test. JUnit4's ExpecteException rule does not help in this case. This is another use case where catch-exception comes in quite handy.
Go to the Installation page to get the latest release. This page provides also the Maven coordinates, prerequisites, and information about dependencies to other libraries.
Thanks to Rod Woo, the former author of catch-exception for creating this awesome library.
Thanks to Szczepan Faber who made some suggestions about a BDD-like syntax for catch-exception. Finally, his ideas triggered the enhancements that came with the 1.0.4 release.
Questions, suggestions and Issues are welcome and can be reported via Issues page of this project.
Please give me feedback of any kind. It is highly appreciated.