Why an exception is thrown out by Mockito? - exception

In the following test code, I make a declaration: when the get() method is called with argument 0, then an exception should be thrown out. In my opinion, if the argument is not 0, the exception should not be thrown out. But, the test was passed. That means get(1) has caused an exception was thrown. Is this a bug of Mockito?
#RunWith(MockitoJUnitRunner.class)
public class MockitoTest {
#Mock
private List<Integer> mockedList;
#Test(expected = Exception.class)
public void test() throws Exception {
when(mockedList.get(0)).thenThrow(new Exception());
mockedList.get(1);
}
}

You set up your test incorrectly and misinterpreted the outcome of your test.
The problem lies in the line:
when(mockedList.get(0)).thenThrow(new Exception());
The signature of "get" method does not allow checked excetions.
Thus, when you pass a checked exception to thenThrow, Mockito rightfully reports it with:
org.mockito.exceptions.base.MockitoException:
Checked exception is invalid for this method!
Invalid: java.lang.Exception
Thus the exception reported is MockitoException, not the Exception you passed to thenThrow. It is thrown even if you omit a call to mockedList.get(1);
To fix, use a RuntimeException, preferrably one that can be reported by get.
when(mockedList.get(0)).thenThrow(new IndexOutOfBoundsException());
Note that you stub a call that is not made afterwards, you need to use a lenient mock with #Mock(lenient = true), otherwise Mockito will report a org.mockito.exceptions.misusing.UnnecessaryStubbingException

Related

InvalidUseOfMatchersException on a different test method

I am getting InvalidUseOfMatchersException on a different test than the one using Matchers
The below two tests are running fine individually but when running together, after the first test passes successfully, second test is failing and throwing InvalidUseOfMatchersException pointing to first test
#Test(expected = InputException.class)
public void shouldThrowExceptionWhenInputNull() {
calculator.calculateA(any(), any(), any(),eq(null));
}
#Test
public void testCalculateB() {
assertTrue(BigDecimal.valueOf(8000).compareTo(calculator.calculateB(12)) == 0);
}
This is the exception in stack trace
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaced or misused argument matcher detected here:
TestClass.shouldThrowExceptionWhenInputNull
According to the exception, first test should fail but its passing and second test is failing. Individually both these tests are passing successfully
calculator.calculateA(any(), any(), any(), eq(null));
This isn't a valid use of Matchers. Mockito only uses any and eq when used with when or verify, as a means of matching invocations that tell Mockito what to return or what calls should have been recorded. You'll need to call calculateA with specific values, such as calculator.calculateA(1, 2, 3, null);.
Mockito matchers work via side effects, so the only time that Mockito can throw an exception is the next time you interact with Mockito. This might be another method, but you can help ensure that those are local by using MockitoRule, MockitoJUnitRunner, or by adding a call to validateMockitoUsage from an #After method:
#After public void validateMockito() {
Mockito.validateMockitoUsage();
}

Test if an assertion is thrown

How do I test if an assertion is thrown by the method under test using junit? Heres the method I'm testing:
public int f(int i){
assert i > 0;
return i;
}
I'm using junit 4.12.
You can test it by providing parameter in #Test annotation:
#Test(expected = AssertionError.class)
public void shouldThrowExceptionWhenIncorrectInput() {
f(-3);
}
This will check if the AssertException is thrown.
However, if you want to ensure that this function wont be run with incorrect parameters, you have to be aware that assertions can be turned off by running java with -da parameters.
To ensure that exception is thrown I would suggest throwing IllegalArgumentException inside some validation method, and to provide it with proper message. Then you will be sure that this will always throw exception when incorrect parameters are provided.

JUnit - Catch an exception in the #After section

I have this scenario in which some tests can throw different exceptions.
#Test
public void addDevice(){
device.addDevice(); // this may throw exception 1
device.verifyStatus("Ready");
device.open(); // this may throw exception 2
device.verifyStatus("Open");
}
#Test
public void otherTest(){
device.act(); // this may throw exception 3
device.verifyStatus("Ready");
}
#After
public void tearDown(){
// handle the exception here
}
I want to handle those exceptions in the #After section without wrapping the test with try, catch.
Is that possible?
No, it is not possible.
You could wrap the test anyway with a try-catch-block. Then you could store the exception to a member variable instead of handling it.
In the #After method you can check whether the exception is null or not.
Due to your comment that you have hundreds of tests with this code I assume that this is set up logic which should actually be in an #Before method.
Thus, you could specify an external resource rule with a before and after method: https://github.com/junit-team/junit/wiki/Rules#externalresource-rules
In the before() method you perform the set up, catch and store the exceptions and in the after() method you handle them.
But does it make sense to handle the exception later? Can you run your test cases successfully if the set up fails?

Handling wrapped exception in Camel

class MyRouteBuilder extends SpringRouteBuilder {
public void configure() throws Exception {
//initialize camel context here
onException(ChildException.class)
.process(new ChildExceptionHandler())
.handled(true)
.to(errorURI);
onException(ParentException.class)
.process(new ParentExceptionHandler())
.handled(true)
.to(errorURI);
from(startURI)
.processRef("someBeanID")
//other processing here
}
}
Now my "someBeanID" throws ChildException while processing, but ParentExceptionHandler is being invoked for that. Code snippet in "someBeanID" is as below
try {
//some processing
throws new ParentException();
} catch (ParentException e) {
throw new ChildException(e); //being handled by ParentExceptionHandler (why?? should be ChildExceptionHandler??)
throw new ChildException(); //being handled by ChildExceptionHandler (should be)
}
It seems that whenever we wrap any exception, Camel automatically finds the actual wrapped exception and invokes handler for that, instead of invoking handler for wrapper exception. Why is this? Is there any problem in my code ??
Thanks,
Finally resolved....Refer to this
When trapping multiple exceptions, the order of the onException clauses is significant. Apache Camel initially attempts to match the thrown exception against the first clause. If the first clause fails to match, the next onException clause is tried, and so on until a match is found. Each matching attempt is governed by the following algorithm:
If the thrown exception is a chained exception (that is, where an exception has been caught and rethrown as a different exception), the most nested exception type serves initially as the basis for matching. This exception is tested as follows:
If the exception-to-test has exactly the type specified in the onException clause (tested using instanceof), a match is triggered.
If the exception-to-test is a sub-type of the type specified in the onException clause, a match is triggered.
If the most nested exception fails to yield a match, the next exception in the chain (the wrapping exception) is tested instead. The testing continues up the chain until either a match is triggered or the chain is exhausted.

Exception assertion along with other assertions jUnit

I have a method that throws exception. And i have a test like this.
#Rule
public ExpectedException expectedEx = ExpectedException.none();
#Test
public void shouldThrowExceptionIfValidationFails() throws Exception {
doThrow(new InvalidException("Invalid Token")).when(obj).foo(any());
expectedEx.expect(InvalidException.class);
expectedEx.expectMessage("Invalid Token");
// my method call
// verify DB save doesn't happens
assertTrue(false);
}
The test assert for exception, and since the exception is thrown the test passes. It doesn't care about the last line assertTrue(false)
How can i make sure that my other assertions are also satisfied.
This is the pattern I follow for this case. It uses ExpectedException as designed. I like the throw e rather than failing after method method call in the try because it will not result in a false-positive if someone decides to delete the fail (which people have a tendency to do when they see fail() or if a test is failing because it hits a fail()).
#Test
public void shouldThrowExceptionIfValidationFails() throws Exception {
doThrow(new InvalidException("Invalid Token")).when(obj).foo(any());
expectedEx.expect(InvalidException.class);
expectedEx.expectMessage("Invalid Token");
try{
// my method call
}catch(InvalidException e){
// verify DB save doesn't happens
assertTrue(false);
throw e;
}
}