Main Tutorials

JUnit – Expected Exceptions Test

In JUnit, there are 3 ways to test the expected exceptions :

  1. @Test, optional ‘expected’ attribute
  2. Try-catch and always fail()
  3. @Rule ExpectedException

P.S Tested with JUnit 4.12

1. @Test expected attribute

Use this if you only want to test the exception type, refer below :

Exception1Test.java

package com.mkyong;

import org.junit.Test;
import java.util.ArrayList;

public class Exception1Test {

    @Test(expected = ArithmeticException.class)
    public void testDivisionWithException() {
        int i = 1 / 0;
    }

    @Test(expected = IndexOutOfBoundsException.class)
    public void testEmptyList() {
        new ArrayList<>().get(0);
    }

}

2. Try-catch and always fail()

This is a bit old school, widely used in JUnit 3. Test the exception type and also the exception detail. Refer below :

Exception2Test.java

package com.mkyong;

import org.junit.Test;
import java.util.ArrayList;
import static junit.framework.TestCase.fail;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

public class Exception2Test {

    @Test
    public void testDivisionWithException() {
        try {
            int i = 1 / 0;
            fail(); //remember this line, else 'may' false positive
        } catch (ArithmeticException e) {
            assertThat(e.getMessage(), is("/ by zero"));
			//assert others
        }
    }

    @Test
    public void testEmptyList() {
        try {
            new ArrayList<>().get(0);
            fail();
        } catch (IndexOutOfBoundsException e) {
            assertThat(e.getMessage(), is("Index: 0, Size: 0"));
        }
    }


}
Always remember the fail()!
If the line you want to test didn’t throw any exception, and you forgot to put the fail(), the test will be passed (false positive).

3. @Rule ExpectedException

This ExpectedException rule (since JUnit 4.7) let you test both the exception type and also the exception detail, same like “2. Try-catch and always fail()” method, but in a more elegant way :

Exception3Test.java

package com.mkyong;

import com.mkyong.examples.CustomerService;
import com.mkyong.examples.exception.NameNotFoundException;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.hasProperty;

public class Exception3Test {

    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Test
    public void testDivisionWithException() {

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

        int i = 1 / 0;

    }

    @Test
    public void testNameNotFoundException() throws NameNotFoundException {

		//test type
        thrown.expect(NameNotFoundException.class);

		//test message
        thrown.expectMessage(is("Name is empty!"));

        //test detail
        thrown.expect(hasProperty("errCode"));  //make sure getters n setters are defined.
        thrown.expect(hasProperty("errCode", is(666)));

        CustomerService cust = new CustomerService();
        cust.findByName("");

    }

}
NameNotFoundException.java

package com.mkyong.examples.exception;

public class NameNotFoundException extends Exception {

    private int errCode;

    public NameNotFoundException(int errCode, String message) {
        super(message);
        this.errCode = errCode;
    }

    public int getErrCode() {
        return errCode;
    }

    public void setErrCode(int errCode) {
        this.errCode = errCode;
    }
}
CustomerService.java

package com.mkyong.examples;

import com.mkyong.examples.exception.NameNotFoundException;

public class CustomerService {

    public Customer findByName(String name) throws NameNotFoundException {

        if ("".equals(name)) {
            throw new NameNotFoundException(666, "Name is empty!");
        }

        return new Customer(name);

    }

}

References

  1. JUnit Wiki Exception Testing
  2. Java Custom Exception Examples

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
8 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Rosalind
9 years ago

Hi Mkyong – I’m always happy when I run into your tutorials. Thanks for doing this.

M Jha
5 years ago

When we use ExceptionRule, and the exception object being thrown has some custom attribute which contains the message (i.e not the getMessage method), how such custom field value/message can be asserted ?

Bhargavi Tanneru
9 years ago

I have a method callFile as following in my code, I want to test it using junit. Can anyone help me in writing the test case

public String callFile(String myFile) {

System.out.println(“Requested File:” + myFile);

StringBuilder stringJson = new StringBuilder();

try {

FileReader logReader = new FileReader(myFile);

BufferedReader buffer = new BufferedReader(logReader);

if (buffer != null) {

int cp;

while ((cp = buffer.read()) != -1) {

stringJson.append((char) cp);

}

buffer.close();

}

}

catch (Exception e) {

throw new RuntimeException(

“Exception while reading File:” + myFile, e);

}

return stringJson.toString();

}

Thanks

Petrit Avdyli
9 years ago

“In above example, the divisionWithException() method will throw an ArithmeticException Exception, since this is an expected exception, so the unit test will pass.”
Too much ex-s in a sentence. But thanks a lot for your tutorials 🙂

vfission
10 years ago

@RunWith(value = Parameterized.class)
public class JunitTest8A {

private TestUDC udc1 , udc2;

public JunitTest8A(String name, int count) {
this.udc1 = new TestUDC(name,count) ;
}

@Parameters
public static Collection data() {
Object[][] data = new Object[][] { { “1”,2 }, {“3”,4 }, {“5”,6}, {“7”,8 } };
return Arrays.asList(data);
}

@Test
public void pushTest() {
System.out.println(“Parameterized UDC is : ” + udc1.getName()+ ” Number2 is : ” + udc1.getCount());
}

}

public class TestUDC
{
public TestUDC(String name, int count)
{
this.name = name;
this.count = count ;
}
private String name;
private int count;
String getName() { return name ; }
int getCount() { return count ; }
}

Hi I enjoyed learning from your tutorials. Please consider including the above example.
I would also include dependency junit-4.4.jar and compilation and run steps.

to Compile
javac -classpath junit-4.4.jar;. java-file
to run
java -cp junit-4.4.jar;. org.junit.runner.JUnitCore java-class-name

As above, I extended it to take multiple parameters String and int.

I tried extending to user defined class as follows

public class TestUDC
{
public TestUDC(String name, int count)
{
this.name = name;
this.count = count ;
}
private String name;
private int count;
String getName() { return name ; }
int getCount() { return count ; }
}

import java.util.Arrays;
import java.util.Collection;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

/**
* JUnit Parameterized Test
* @author mkyong extended by Raman Kannan
*
*/
@RunWith(value = Parameterized.class)
public class JunitTest8 {

private TestUDC udc1 , udc2;

public JunitTest8(TestUDC udc) {
this.udc1 = udc1 ;
}

@Parameters
public static Collection data() {
Object[][] data = new Object[][] { { new TestUDC(“1”,2) }, {new TestUDC(“3”,4) }, { new TestUDC(“5”,6 )}, {new TestUDC(“7”,8) } };
return Arrays.asList(data);
}

@Test
public void pushTest() {
System.out.println(“Parameterized UDC is : ” + udc1.getName()+ ” Number2 is : ” + udc1.getCount());
}

}

This does not appear to run..compiles ok but does not run..throws some exception.

thanks
vf

AA Mathieu
11 years ago

Very nice tutorials! Thanks a lot!

club penguin
12 years ago

nice blog! thanks for the help.

krishna
7 years ago

share link to download examples in each tutorial