What if you could make your tests throw errors exactly when you want, like magic?
Why when().thenThrow() for exceptions in JUnit? - Purpose & Use Cases
Imagine you have a program that calls a service to get data. Sometimes, this service might fail and throw an error. If you test this by running the real service every time, you must wait and watch carefully to see if the error happens.
This is like calling a friend to ask for help, but you never know if they will pick up or be busy. You have to keep trying and hope for the best.
Testing errors manually is slow and unreliable. You might miss the error if it happens rarely. Also, you cannot control when the error happens, so your tests become flaky and confusing.
It is like trying to catch a rare bird by waiting outside all day without knowing when it will appear.
Using when().thenThrow() lets you tell your test exactly when to throw an error. You can simulate the error anytime you want, without calling the real service.
This makes your tests fast, reliable, and easy to understand. You control the error, so you can check how your program handles it perfectly.
callRealService(); // hope it throws error sometimes checkIfErrorHandled();
when(mockService.call()).thenThrow(new RuntimeException()); callServiceAndCheckError();
You can easily test how your program reacts to errors without waiting or guessing.
Testing a payment system where the payment gateway might fail. Instead of waiting for real failures, you simulate the failure to check if your system shows the right error message to users.
Manual error testing is slow and unreliable.
when().thenThrow() simulates errors on demand.
This makes tests faster, stable, and clear.
Practice
when().thenThrow() in JUnit tests?Solution
Step 1: Understand the role of
This syntax is used in mocking frameworks like Mockito to simulate exceptions when a mocked method is called.when().thenThrow()Step 2: Identify the purpose in testing
It helps test how your code handles exceptions by forcing the mocked method to throw an exception.Final Answer:
To simulate an exception being thrown by a mocked method -> Option DQuick Check:
Exception simulation [OK]
- Confusing exception simulation with return value mocking
- Thinking it creates real exceptions instead of simulated ones
- Using it to skip tests instead of throwing exceptions
IllegalArgumentException using Mockito?Solution
Step 1: Recall Mockito syntax for throwing exceptions
The correct syntax useswhen(mock.method()).thenThrow(new ExceptionType()).Step 2: Match the options with correct syntax
when(mock.method()).thenThrow(new IllegalArgumentException()) matches the correct syntax exactly, creating a new exception instance insidethenThrow().Final Answer:
when(mock.method()).thenThrow(new IllegalArgumentException()) -> Option BQuick Check:
Correct Mockito exception syntax [OK]
- Using throwException or throws which are not Mockito methods
- Not creating a new exception instance
- Calling thenThrow directly on mock.method()
MyService mockService = mock(MyService.class);
when(mockService.getData()).thenThrow(new RuntimeException("Error"));
assertThrows(RuntimeException.class, () -> mockService.getData());Solution
Step 1: Analyze the mocking behavior
The mocked methodgetData()is set to throw aRuntimeExceptionwhen called.Step 2: Understand the assertion
assertThrowsexpects aRuntimeExceptionfrom callingmockService.getData().Final Answer:
Test passes because RuntimeException is thrown as expected -> Option AQuick Check:
Exception thrown matches assertThrows [OK]
- Assuming no exception is thrown from mocked method
- Confusing exception types in assertThrows
- Thinking thenThrow causes syntax errors
when(mockService.getData()).thenThrow(RuntimeException.class); assertThrows(RuntimeException.class, () -> mockService.getData());
Solution
Step 1: Check thenThrow argument type
thenThrowrequires an exception instance, not a class type.Step 2: Identify correct usage
The code should usethenThrow(new RuntimeException())instead of passing the class.Final Answer:
Incorrect use of thenThrow with exception class instead of instance -> Option CQuick Check:
thenThrow needs exception instance [OK]
- Passing exception class instead of instance to thenThrow
- Expecting assertThrows to catch exceptions without mocking
- Adding unnecessary try-catch in test
NullPointerException thrown by a dependency's void call() method. Which of the following code snippets correctly mocks the dependency and verifies the exception handling using JUnit and Mockito?Solution
Step 1: Understand mocking exceptions with void methods
Ifdependency.call()is a void method,doThrow().when()is the correct way to mock exceptions.Step 2: Verify correct assertion
assertThrows(NullPointerException.class, () -> service.callDependency())correctly checks that the service handles the exception.Step 3: Analyze options
when(dependency.call()).thenThrow(new NullPointerException()); assertThrows(NullPointerException.class, () -> service.callDependency()); useswhen().thenThrow()which works only for non-void methods. when(dependency.call()).thenThrow(NullPointerException.class); assertThrows(Exception.class, () -> service.callDependency()); passes class instead of instance and wrong exception type in assertion. when(dependency.call()).thenReturn(null); assertThrows(NullPointerException.class, () -> service.callDependency()); returns null instead of throwing exception.Final Answer:
doThrow(new NullPointerException()).when(dependency).call(); assertThrows(NullPointerException.class, () -> service.callDependency()); -> Option AQuick Check:
Use doThrow for void methods + assertThrows [OK]
- Using thenThrow() on void methods
- Passing exception class instead of instance
- Asserting wrong exception type
- Returning null instead of throwing exception
Ready to prove it?
Pass the test and this pattern moves unknown
