JUnit 5 Expected Exception – assertThrows() Example

In JUnit 5, to write the test code that is expected to throw an exception, we should use Assertions.assertThrows().

In the given example, the test code in the commented block is expected to throw an exception of type ApplicationException.

@Test
void testExpectedException() {

  ApplicationException thrown = Assertions.assertThrows(ApplicationException.class, () -> {
           //Code under test
  });

  Assertions.assertEquals("some message", exception.getMessage());
}

1. Assertions assertThrows() API

1.1. Syntax

The assertThrows() method asserts that execution of the supplied executable block or lambda expression throws an exception of the expectedType. It is an overloaded method and takes the following parameters.

static <T extends Throwable>T assertThrows(Class<T> expectedType, Executable executable)

static <T extends Throwable>T assertThrows(Class<T> expectedType, Executable executable, String message)

static <T extends Throwable>T assertThrows(Class<T> expectedType, Executable executable, Supplier<String> messageSupplier)
  • expectedType – Test code is expected to throw an exception of this type.
  • message – If the executable code does not throw any exception, this message will be printed along with FAIL result.
  • messageSupplier – The message will be retrieved from it in case the test fails.

1.2. Test Output

If no exception is thrown from the executable block then assertThrows() will FAIL.
If an exception of a different type is thrownassertThrows() will FAIL.
If the code block throws an exception of a class that is a subtype of the expectedType exception only then the assertThrows() will PASS.

For example, if we are expecting IllegalArgumentException and the test throws NumberFormatException then also the test will PASS because NumberFormatException extends IllegalArgumentException class.

Also, if we pass Exception.class as the expected exception type, any exception thrown from the executable block will make the assertion PASS since Exception is the super-type for all exceptions.

2. Expected exception is thrown from the test

Given below is a very simple test that expects NumberFormatException to be thrown when the supplied code block is executed.

@Test
void testExpectedException() {

	NumberFormatException thrown = Assertions.assertThrows(NumberFormatException.class, () -> {
		Integer.parseInt("One");
	}, "NumberFormatException was expected");
	
	Assertions.assertEquals("For input string: \"One\"", thrown.getMessage());
}

@Test
void testExpectedExceptionWithParentType() {

	Assertions.assertThrows(IllegalArgumentException.class, () -> {
		Integer.parseInt("One");
	});
}
  • In testExpectedException, The executable code is Integer.parseInt("One") which throws NumberFormatException if method argument is not a valid numeric number. The assertThrows() the method expects – so this exception so the test result is PASS.
  • In testExpectedExceptionWithParentType, we are executing the same code but this time we are excepting IllegalArgumentException which is the parent of NumberFormatException. This test also passes.

3. Exception thrown is of a different type; or No exception is thrown

If executable code throws any other exception type, then the test will FAIL.

And even if the executable code does not throw any exception, then also test will FAIL.

For example, in below example "1" is a valid number so no exception will be thrown. This test will fail with the message in the console.

@Test
void testExpectedExceptionFail() {
 
	NumberFormatException thrown = Assertions
				.assertThrows(NumberFormatException.class, () -> {
					Integer.parseInt("1");
				}, "NumberFormatException error was expected");
	
	Assertions.assertEquals("Some expected message", thrown.getMessage());
}
Junit message

In this post, we learned how to write a test that expects exceptions to be thrown. These tests are helpful in testing the code written in the catch blocks.

Happy Learning !!

Sourcecode Download

Was this post helpful?

Join 7000+ Awesome Developers

Get the latest updates from industry, awesome resources, blog updates and much more.

* We do not spam !!

7 thoughts on “JUnit 5 Expected Exception – assertThrows() Example”

  1. Nice tutorial!
    But I think the sentence below should be corrected.
    “e.g. If you are expecting NumberFormatException and it throws IllegalArgumentException then also the test will PASS because NumberFormatException extends IllegalArgumentException class.”

    It is supposed to be:
    e.g. If you are expecting IllegalArgumentException and it throws NumberFormatException then also the test will PASS because NumberFormatException extends IllegalArgumentException class.

    Reply
  2. Hello Sir, below is the part of the code I want cover test cases. how can I cover the requestException part of this code?

    @Override
    public CustomerAMLModResponse transform(DoCustAMLInfoModRs_Type soapResponseWrapper, 
                                ClientMetaData metaData) throws RequestException {
    
    CustomerAMLModResponse custAMLModRestRs = new CustomerAMLModResponse();
    
    List<JAXBElement> listJAXBE = soapResponseWrapper.getContent();
    CustAMLInfoModRs_Type custAMLInfoModSoapRs;
    Status_Type status = null;
    
    for (int i = 0; i < listJAXBE.size(); i++) {
    JAXBElement elem = listJAXBE.get(i);
    if ( elem.getValue() instanceof CustAMLInfoModRs_Type ) {
    custAMLInfoModSoapRs = (CustAMLInfoModRs_Type) elem.getValue();
    status = custAMLInfoModSoapRs.getStatus();
    break;
    } else if ( elem.getValue() instanceof Status_Type ){
    status = (Status_Type) elem.getValue();
    break;
    }
    }
    
    if ( status !=null && status.getStatusCode() != 0L && 
          !status.getServerStatusCode().equals(CustAMLConstants.WSSERVER_STATUS_CODE_SUCCESS) ) {
    logger.error(“Customer AML Mod Response contains error code”);
    throw new RequestException( validationUtils.prepErrosList(status) );
    }
    
    return custAMLModRestRs;
    
    }
    
    Reply
  3. Hello Sir, below is the part of the code I want cover test cases. how can I cover the requestException part of this code?
    @Override
    public CustomerAMLModResponse transform(DoCustAMLInfoModRs_Type soapResponseWrapper, ClientMetaData metaData) throws RequestException {

    CustomerAMLModResponse custAMLModRestRs = new CustomerAMLModResponse();

    List<JAXBElement> listJAXBE = soapResponseWrapper.getContent();
    CustAMLInfoModRs_Type custAMLInfoModSoapRs;
    Status_Type status = null;

    for (int i = 0; i < listJAXBE.size(); i++) {
    JAXBElement elem = listJAXBE.get(i);
    if ( elem.getValue() instanceof CustAMLInfoModRs_Type ) {
    custAMLInfoModSoapRs = (CustAMLInfoModRs_Type) elem.getValue();
    status = custAMLInfoModSoapRs.getStatus();
    break;
    } else if ( elem.getValue() instanceof Status_Type ){
    status = (Status_Type) elem.getValue();
    break;
    }
    }

    if ( status !=null && status.getStatusCode() != 0L && !status.getServerStatusCode().equals(CustAMLConstants.WSSERVER_STATUS_CODE_SUCCESS) ) {
    logger.error(“Customer AML Mod Response contains error code”);
    throw new RequestException( validationUtils.prepErrosList(status) );
    }

    return custAMLModRestRs;

    }

    Reply

Leave a Comment

HowToDoInJava

A blog about Java and related technologies, the best practices, algorithms, and interview questions.