Exception assertion along with other assertions jUnit - exception

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;
}
}

Related

Why an exception is thrown out by Mockito?

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

Express "success" or "throw exception" of Vavr Try in Java unit test

I have a simple unit test which asserts on an object instance of Try from the vavr library.
#Test
public void testFoo()
{
final Try<Foo> result = createMyFooInstance();
assertThat(result.isSuccess()).isTrue();
}
My question focuses on the formulation of the test assertion.
Semantically I want to have "if foo is success, all fine, otherwise, throw the encapsulated exception". The latter one is important so that I can see the error cause directly in the JUnit output.
Is there any convenient API that I can use to nicely formulate that semantics?
You could use
#Test
public void testFoo() {
final Try<Foo> result = createMyFooInstance();
result.get();
}
In case when result is a Failure, result.get() will throw the wrapped exception. In case when result is a Success, it will succeed.
Though this solution doesn't contain explicit assertions, it will implicitly fail the cases when the result is a Failure.
If you prefer to have an assertion failed instead of a test failed with exception, you could also use:
#Test
public void testFoo() {
final Try<Foo> result = createMyFooInstance();
assertThatCode(result::get).doesNotThrowAnyException();
}

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?

Webdriver test Script Does not stop after assert failure

In my webdriver script I have the three methods
setup, test and tearDown
following the junit convention.
In the test method I have few asserts like this
#Test
public void testStudentHome() throws Exception {
String classCode = "I6OWW";
Utilities.studentSignin(driver, baseUrl);
assertEquals(true, sth.openNotification());
assertEquals("My Scores", sth.myScores(true));
}
The sth is the PageObject on which I am performing the tests and that I have created in the setup method.
I am calling all these three methods from a main method like this:
public static void main(String[] args) {
StudentHomeTest sht = new StudentHomeTest();
try {
sht.setup();
sht.testStudentHome();
sht.tearDown();
} catch (Exception ex) {
Logger.getLogger(StudentHomeTest.class.getName()).log(Level.SEVERE, null, ex);
sht.tearDown();
}
}
Now while running the test if some assertion fails the test method should (this is what I expect) throw an exception and the main method should call the tearDown method. But this does not happen. and the browser window continues to stay there.
I am using the netbeans ide for running the test.
following the junit convention
If you follow the jUnit convention, then you will know that teardown methods belong in the #After method as this method will always run after your tests.
create a new method with the #After jUnit annotation.
#After
public void tearDown() {
sht.tearDown();
}
Edit
You know what, I believe that you are running into a classic issue of assertEquals in jUnit.
Stolen from this answer...:
JUnit calls the .equals() method to determine equality in the method assertEquals(Object o1, Object o2).
So, you are definitely safe using assertEquals(string1, string2). (Because Strings are Objects)
--
Instead of using assertEquals on these calls, use assertTrue() instead.
assertTrue(sth.openNotification());
assertTrue("My Scores".equals(sth.myScores(true)));
AssertionError doesn't extend Exception - it's a Throwable.
But in any case, you should have
try {
sht.setup();
sht.testStudentHome();
} finally {
sht.tearDown();
}
No need for a catch block. main can throw Exception.