Intermediate level · Module 5: Unit Testing with JUnit 5 · Lesson 2 of 3
Testing Edge Cases and Exceptions
Test boundaries and error paths, check that exceptions are thrown, and remove duplication with @BeforeEach and parameterized tests.
In this lesson you will
- Use assertThrows to test error handling
- Write parameterized tests for several inputs
Key concepts
boundary valueassertThrows@BeforeEach@ParameterizedTest
The lesson
Most bugs hide at the edges: zero, one, the maximum allowed, just above the maximum, empty input. If a member may borrow three books, test two, three and four.
assertThrows(LoanLimitException.class, () -> service.lend(member, book)) passes only if the code throws that exception. It proves that rules are enforced, not just that the happy path works.
@BeforeEach runs before every test, so shared setup lives in one place. @ParameterizedTest with @ValueSource or @CsvSource runs one test method with many inputs, which keeps boundary testing short and readable.
Step by step
- Move repeated setup into an @BeforeEach method.
- Test the loan limit at 2, 3 and 4 books.
- Use assertThrows for the fourth loan.
- Rewrite the boundary tests as one parameterized test.
Practice activity
Write tests for every rule of the loan service, including all boundaries and every custom exception.
Expected result: Each rule has a passing and a failing case, and every custom exception is tested with assertThrows.
Check your understanding
-
What does assertThrows check?
Show answer
That running the given code throws the expected type of exception.
-
If a limit is three, which values should you test?
Show answer
Values just below, at and above the limit: two, three and four.
Taught live by an instructor — online or in person. Free course lessons are for self-study and do not lead to a certificate — see registration options.