[java] How to test that no exception is thrown?

I know that one way to do it would be:

@Test
public void foo() {
   try {
      // execute code that you expect not to throw Exceptions.
   } catch(Exception e) {
      fail("Should not have thrown any exception");
   }
}

Is there any cleaner way of doing this? (Probably using Junit's @Rule?)

This question is related to java unit-testing exception junit junit4

The answer is


JUnit 5 (Jupiter) provides three functions to check exception absence/presence:

? assertAll?()

Asserts that all supplied executables
  do not throw exceptions.

? assertDoesNotThrow?()

Asserts that execution of the
  supplied executable/supplier
does not throw any kind of exception.

  This function is available
  since JUnit 5.2.0 (29 April 2018).

? assertThrows?()

Asserts that execution of the supplied executable
throws an exception of the expectedType
  and returns the exception.

Example

package test.mycompany.myapp.mymodule;

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Test;

class MyClassTest {

    @Test
    void when_string_has_been_constructed_then_myFunction_does_not_throw() {
        String myString = "this string has been constructed";
        assertAll(() -> MyClass.myFunction(myString));
    }

    @Test
    void when_string_has_been_constructed_then_myFunction_does_not_throw__junit_v520() {
        String myString = "this string has been constructed";
        assertDoesNotThrow(() -> MyClass.myFunction(myString));
    }

    @Test
    void when_string_is_null_then_myFunction_throws_IllegalArgumentException() {
        String myString = null;
        assertThrows(
            IllegalArgumentException.class,
            () -> MyClass.myFunction(myString));
    }

}

Use assertNull(...)

@Test
public void foo() {
    try {
        //execute code that you expect not to throw Exceptions.
    } catch (Exception e){
        assertNull(e);
    }
}

I stumbled upon this because of SonarQube's rule "squid:S2699": "Add at least one assertion to this test case."

I had a simple test whose only goal was to go through without throwing exceptions.

Consider this simple code:

public class Printer {

    public static void printLine(final String line) {
        System.out.println(line);
    }
}

What kind of assertion can be added to test this method? Sure, you can make a try-catch around it, but that is only code bloat.

The solution comes from JUnit itself.

In case no exception is thrown and you want to explicitly illustrate this behaviour, simply add expected as in the following example:

@Test(expected = Test.None.class /* no exception expected */)
public void test_printLine() {
    Printer.printLine("line");
}

Test.None.class is the default for the expected value.


You can do it by using a @Rule and then call method reportMissingExceptionWithMessage as shown below: This is Scala code.

enter image description here


If you are unlucky enough to catch all errors in your code. You can stupidly do

class DumpTest {
    Exception ex;
    @Test
    public void testWhatEver() {
        try {
            thisShouldThrowError();
        } catch (Exception e) {
            ex = e;
        }
        assertEquals(null,ex);
    }
}

This may not be the best way but it definitely makes sure that exception is not thrown from the code block that is being tested.

import org.assertj.core.api.Assertions;
import org.junit.Test;

public class AssertionExample {

    @Test
    public void testNoException(){
        assertNoException();
    }    

    private void assertException(){
        Assertions.assertThatThrownBy(this::doNotThrowException).isInstanceOf(Exception.class);
    }

    private void assertNoException(){
        Assertions.assertThatThrownBy(() -> assertException()).isInstanceOf(AssertionError.class);
    }

    private void doNotThrowException(){
        //This method will never throw exception
    }
}

The following fails the test for all exceptions, checked or unchecked:

@Test
public void testMyCode() {

    try {
        runMyTestCode();
    } catch (Throwable t) {
        throw new Error("fail!");
    }
}

You can expect that exception is not thrown by creating a rule.

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

To test a scenario with a void method like

void testMeWell() throws SomeException {..}

to not throw an exception:

Junit5

assertDoesNotThrow(() -> {
    testMeWell();
});

Java 8 makes this a lot easier, and Kotlin/Scala doubly so.

We can write a little utility class

class MyAssertions{
  public static void assertDoesNotThrow(FailingRunnable action){
    try{
      action.run()
    }
    catch(Exception ex){
      throw new Error("expected action not to throw, but it did!", ex)
    }
  }
}

@FunctionalInterface interface FailingRunnable { void run() throws Exception }

and then your code becomes simply:

@Test
public void foo(){
  MyAssertions.assertDoesNotThrow(() -> {
    //execute code that you expect not to throw Exceptions.
  }
}

If you dont have access to Java-8, I would use a painfully old java facility: aribitrary code blocks and a simple comment

//setup
Component component = new Component();

//act
configure(component);

//assert 
/*assert does not throw*/{
  component.doSomething();
}

And finally, with kotlin, a language I've recently fallen in love with:

fun (() -> Any?).shouldNotThrow() 
    = try { invoke() } catch (ex : Exception){ throw Error("expected not to throw!", ex) }

@Test fun `when foo happens should not throw`(){

  //...

  { /*code that shouldn't throw*/ }.shouldNotThrow()
}

Though there is a lot of room to fiddle with exactly how you want to express this, I was always a fan of fluent assertions.


Regarding

You're approaching this the wrong way. Just test your functionality: if an exception is thrown the test will automatically fail. If no exception is thrown, your tests will all turn up green.

This is correct in principle but incorrect in conclusion.

Java allows exceptions for flow of control. This is done by the JRE runtime itself in APIs like Double.parseDouble via a NumberFormatException and Paths.get via a InvalidPathException.

Given you've written a component that validates Number strings for Double.ParseDouble, maybe using a Regex, maybe a hand-written parser, or perhaps something that embeds some other domain rules that restricts the range of a double to something specific, how best to test this component? I think an obvious test would be to assert that, when the resulting string is parsed, no exception is thrown. I would write that test using either the above assertDoesNotThrow or /*comment*/{code} block. Something like

@Test public void given_validator_accepts_string_result_should_be_interpretable_by_doubleParseDouble(){
  //setup
  String input = "12.34E+26" //a string double with domain significance

  //act
  boolean isValid = component.validate(input)

  //assert -- using the library 'assertJ', my personal favourite 
  assertThat(isValid).describedAs(input + " was considered valid by component").isTrue();
  assertDoesNotThrow(() -> Double.parseDouble(input));
}

I would also encourage you to parameterize this test on input using Theories or Parameterized so that you can more easily re-use this test for other inputs. Alternatively, if you want to go exotic, you could go for a test-generation tool (and this). TestNG has better support for parameterized tests.

What I find particularly disagreeable is the recommendation of using @Test(expectedException=IllegalArgumentException.class), this exception is dangerously broad. If your code changes such that the component under test's constructor has if(constructorArgument <= 0) throw IllegalArgumentException(), and your test was supplying 0 for that argument because it was convenient --and this is very common, because good generating test data is a surprisingly hard problem--, then your test will be green-bar even though it tests nothing. Such a test is worse than useless.


I faced the same situation, I needed to check that exception is thrown when it should, and only when it should. Ended up using the exception handler to my benefit with the following code:

    try {
        functionThatMightThrowException()
    }catch (Exception e){
        Assert.fail("should not throw exception");
    }
    RestOfAssertions();

The main benefit for me was that it is quite straight forward and to check the other way of the "if and only if" is really easy in this same structure


Although this post is 6 years old now, however, a lot has changed in the Junit world. With Junit5, you can now use

org.junit.jupiter.api.Assertions.assertDoesNotThrow()

Ex:

public void thisMethodDoesNotThrowException(){
   System.out.println("Hello There");
}

@Test
public void test_thisMethodDoesNotThrowException(){
  org.junit.jupiter.api.Assertions.assertDoesNotThrow(
      ()-> thisMethodDoesNotThrowException()
    );
}

Hope it will help people who are using newer version of Junit5


If you want to test that whether your test target consumes the exception. Just leave the test as (mock collaborator using jMock2):

@Test
public void consumesAndLogsExceptions() throws Exception {

    context.checking(new Expectations() {
        {
            oneOf(collaborator).doSth();
            will(throwException(new NullPointerException()));
        }
    });

    target.doSth();
 }

The test would pass if your target does consume the exception thrown, otherwise the test would fail.

If you want to test your exception consumption logic, things get more complex. I suggest delegating the consumption to a collaborator which could be mocked. Therefore the test could be:

@Test
public void consumesAndLogsExceptions() throws Exception {
    Exception e = new NullPointerException();
    context.checking(new Expectations() {
        {
            allowing(collaborator).doSth();
            will(throwException(e));

            oneOf(consumer).consume(e);
        }
    });

    target.doSth();
 }

But sometimes it's over-designed if you just want to log it. In this case, this article(http://java.dzone.com/articles/monitoring-declarative-transac, http://blog.novoj.net/2008/09/20/testing-aspect-pointcuts-is-there-an-easy-way/) may help if you insist tdd in this case.


You can create any kind of your own assertions based on assertions from junit:

static void assertDoesNotThrow(Executable executable) {
    assertDoesNotThrow(executable, "must not throw");
}
static void assertDoesNotThrow(Executable executable, String message) {
    try {
        executable.execute();
    } catch (Throwable err) {
        fail(message);
    }
}

And test:

//the following will succeed
assertDoesNotThrow(()->methodMustNotThrow(1));
assertDoesNotThrow(()->methodMustNotThrow(1), "fail with specific message: facepalm");
//the following will fail
assertDoesNotThrow(()->methodMustNotThrow(2));
assertDoesNotThrow(()-> {throw new Exception("Hello world");}, "Fail: must not trow");

Generally speaking there is possibility to instantly fail("bla bla bla") the test in any scenarios, in any place where it makes sense. For instance use it in a try/catch block to fail if anything is thrown in the test case:

try{methodMustNotThrow(1);}catch(Throwable e){fail("must not throw");}
//or
try{methodMustNotThrow(1);}catch(Throwable e){Assertions.fail("must not throw");}

This is the sample of the method we test, supposing we have such a method that must not fail under specific circumstances, but it can fail:

void methodMustNotThrow(int x) throws Exception{
    if (x == 1) return;
    throw new Exception();
}

The above method is a simple sample. But this works for complex situations, where the failure is not so obvious. There are the imports:

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import static org.junit.jupiter.api.Assertions.*;

JUnit5 adds the assertAll() method for this exact purpose.

assertAll( () -> foo() )

source: JUnit 5 API


With AssertJ fluent assertions 3.7.0:

Assertions.assertThatCode(() -> toTest.method())
    .doesNotThrowAnyException();

Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to unit-testing

Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0 How to test the type of a thrown exception in Jest Unit Tests not discovered in Visual Studio 2017 Class Not Found: Empty Test Suite in IntelliJ Angular 2 Unit Tests: Cannot find name 'describe' Enzyme - How to access and set <input> value? Mocking HttpClient in unit tests Example of Mockito's argumentCaptor How to write unit testing for Angular / TypeScript for private methods with Jasmine Why is the Visual Studio 2015/2017/2019 Test Runner not discovering my xUnit v2 tests

Examples related to exception

Connection Java-MySql : Public Key Retrieval is not allowed How to print an exception in Python 3? ASP.NET Core Web API exception handling Catching FULL exception message How to get exception message in Python properly What does "Fatal error: Unexpectedly found nil while unwrapping an Optional value" mean? what does Error "Thread 1:EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)" mean? Argument Exception "Item with Same Key has already been added" The given key was not present in the dictionary. Which key? sql try/catch rollback/commit - preventing erroneous commit after rollback

Examples related to junit

Eclipse No tests found using JUnit 5 caused by NoClassDefFoundError for LauncherFactory How to resolve Unneccessary Stubbing exception JUnit 5: How to assert an exception is thrown? How do I mock a REST template exchange? Class Not Found: Empty Test Suite in IntelliJ Unable to find a @SpringBootConfiguration when doing a JpaTest Failed to load ApplicationContext (with annotation) Example of Mockito's argumentCaptor Mockito - NullpointerException when stubbing Method Spring jUnit Testing properties file

Examples related to junit4

Mockito: Mock private field initialization java.lang.Exception: No runnable methods exception in running JUnits How to write JUnit test with Spring Autowire? How to run JUnit tests with Gradle? Difference between @Before, @BeforeClass, @BeforeEach and @BeforeAll How to test that no exception is thrown? Failed to load ApplicationContext for JUnit test of Spring controller How does Junit @Rule work? maven error: package org.junit does not exist How do I assert an Iterable contains elements with a certain property?