Testing Expected Exceptions (JUnit)

When we test, we expect some exceptions to take place. Here we will see different ways to test methods with expected exceptions.

junit

Objectives:

  • How to write test cases that test expected exceptions?

Environment & Tools:

  • Eclipse
  • Maven

Libraries:

  • JUnit (4.11)
  • hamcrest-core (1.3)
  • For complete list of jar files: .classpath
  • For complete list of Maven dependencies: pom.xml

( 1 ) Simple Test

This is enough to test simple cases.

Here we initiate a String variable with null, then we try to apply toUpperCase() method. We know that it should throw NullPointerException or we expected it!

package com.hmkcode;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public class AppTest 
{
	 @Test(expected= NullPointerException.class) 
	  public void testNull() { 
	       String str = null;
	       str.toUpperCase();
	  } 	
}

( 2 ) Test Exception Message

Here is a more advanced way to test expected exception. We use Try/catch if the exception we expected is not thrown the test will fail. Also, if we did not get the expected exception message the test will fail.

package com.hmkcode;

import java.util.LinkedList;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.hamcrest.CoreMatchers.is;

@RunWith(JUnit4.class)
public class AppTest 
{
	 @Test
	 public void testExceptionMessage(){
		 try{
			 new LinkedList<Object>().get(0);

			 //if no exception thrown the test will fail with the below message.
			 fail("Expected an IndexOutOfBoundsException to be thrown");

	      } catch (IndexOutOfBoundsException anIndexOutOfBoundsException) {

	    	  //if no exception message is not the same the test will fail with the below message.
	          assertThat(anIndexOutOfBoundsException.getMessage(), is("Index: 0, Size: 0"));
	      }

	 }
}

( 3 ) Using @Rule

We have another way to test expected exception and expected exception message, it is @Rule

package com.hmkcode;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public class AppTest 
{
  	  @Rule
	  public ExpectedException thrown = ExpectedException.none();

	  @Test
	  public void testExceptionByRule() throws ArithmeticException {

	        thrown.expect(ArithmeticException.class);
	        thrown.expectMessage("/ by zero");

	    	double d = 1 / 0;
	   }

}

Source Code @ GitHub