Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JUnit4 expected exception

Tags:

java

junit

junit4

I'm making scenario tests with JUnit4 for a project.

In one of the tests I need to check for an expected exception. With JUnit4 I do this using the annotation.

 @Test(expected=...) 

Now the problem is that underneath the code in the test that throws the exception there's some other annotations I need to check which doesn't get excecuted. An example given:

   @Test(expected=NullPointerException.class)
     public void nullPointerTest() {
         Object o = null;
         o.toString();
         assertTrue(false);
     }

This tests passes because it gets the nullpointerexception however there's obviously an assertion error with the asserTrue(false) and thus I want it to fail.

What's the best way to fix this? A solution to this could be the following, but I don't know if this is the correct way to do it.

@Test
public void nullPointerTest2() {
    boolean caught = false;
    try{
        Object o = null;
        o.toString();
    }
    catch(NullPointerException e)
    {
        caught = true;
    }
    assertTrue(caught);
    assertTrue(false);
}

This second test fails as predicted.

like image 201
user757926 Avatar asked Mar 03 '26 03:03

user757926


2 Answers

Consider:

@Test(expected=NullPointerException.class)
public void nullPointerTest2() {
  boolean caught = false;
  try{
     Object o = null;
     o.toString();
  }
  catch(NullPointerException e)
  {
    // test other stuff here
     throw e;
  }
}

This allows for additional checks while still taking full advantage of JUnit's built-in exception checking.

Also, I consider the use of @Rule ExpectedException to be a better option that expected in many cases.

like image 145
John B Avatar answered Mar 04 '26 15:03

John B


JUnit4 is behaving as expected: when an exception is thrown, execution does not continue. So the NullPointerException gets thrown, the test method exits, JUnit4 marks it as passing because you expected an exception. The code after the null dereference effectively does not exist.

If you want the behavior of the second test, then what you've written is a good solution. But it's a weird thing to want. It seems to me that you are conflating two different tests. One test should test that an exception is thrown under exceptional circumstances. A second test should test whatever the second assertion checks.

like image 26
Nathaniel Waisbrot Avatar answered Mar 04 '26 15:03

Nathaniel Waisbrot