1

i have this code in my program which is needed to be tested with jUnit

 void deleteCustomer(String name) throws UnknownCustomerException,
        AccountNotEmptyException {
    if (name == null) {
        throw new NullPointerException();
    } else if (!exists(name)) {
        throw new UnknownCustomerException();
    } else if (getCustomer(name).deletable()) {
        customerList.remove(getCustomer(name));
    }
}

I thought i can test it in one JUnit method like

   @Test
public void createCustomer(){
    System.out.println("createCustomerTest");
    try {
        element.createCustomer(null);
        //fail("Expected an IndexOutOfBoundsException to be thrown");
    } catch (NullPointerException anIndexOutOfBoundsException) {
        assertTrue(anIndexOutOfBoundsException.getMessage().equals("NullPointerException"));
    }
}

As you can see I already tried unsuccessfully to implement the NPE. How can I check for several Exceptions in one JUnit Method? I checked some How-To's in the web but failed with that too.

5
  • 7
    1) have separate tests for each of the exceptions; 2) if you are unsuccessful in testing one exception, get that working before trying to test the others. Commented Mar 24, 2016 at 7:07
  • 1
    I agree as well. Always try to test one thing with each test method. Also use expected exception unless you want to test exception details (like the message). Commented Mar 24, 2016 at 7:13
  • Just to clarify, if you're testing for an exception and you get it, the test passed; don't catch them. Commented Mar 24, 2016 at 7:16
  • 2
    Use assertEquals(a, b) instead of assertTrue(a.equals(b)). Commented Mar 24, 2016 at 7:18
  • 2
    your test method name confuses me btw. what are you testing? the customer deletion or custumer creation? it is also useful to include what the test shall check in the test name like createCustumer_shouldThrowNullpointerIf...() Commented Mar 24, 2016 at 7:27

4 Answers 4

8

I think in your case you should have separate tests, however you can achieve this like so if using Java 8:

Using an AssertJ 3 assertion, which can be used alongside JUnit:

import static org.assertj.core.api.Assertions.*;

@Test
public void test() {
  Element element = new Element();

  assertThatThrownBy(() -> element.createCustomer(null))
        .isInstanceOf(NullPointerException.class)
        .hasMessageContaining("NullPointerException");

  assertThatThrownBy(() -> element.get(1))
        .isInstanceOf(IndexOutOfBoundsException.class);
}

It's better than @Test(expected=IndexOutOfBoundsException.class) or .expect syntax because it guarantees the expected line in the test threw the exception and lets you check more details about the exception, such as message.

Maven/Gradle instructions here.

Sign up to request clarification or add additional context in comments.

1 Comment

that looks quit good but i dont get this running with intellij. One their page they write: IntelliJ Idea No special configuration, just start typing assertThat and then invoke completion (Ctrl-Space) twice.
2

Write for each exception its own test. It will be only one thrown at a time anyway.
For example a simplified method:

    void deleteCustomer( String name ) throws UnknownCustomerException
    {
        if ( name == null )
        {
            throw new NullPointerException();
        }
        else if ( !exists( name ) )
        {
            throw new UnknownCustomerException();
        }
    }

You have then two tests that each check if its exception is thrown:

@Test( expected = NullPointerException.class )
public void deleteCustomer_shouldThrowNullpointerIfNameIsNull() throws UnknownCustomerException
{
    String name = null;
    cut.deleteCustomer( name );
}

@Test( expected = UnknownCustomerException.class )
public void deleteCustomer_shouldThrowUnknownCustomerExceptionIfNameIsUnknown() throws UnknownCustomerException
{
    String name = "someUnknownName";
    cut.deleteCustomer( name );
}

The problem with the NullpointerException is, that the test is true/successful/green if the NPE is thrown anywhere in the method - so you should make sure, that that is not happening for the test to be meaningful.

Comments

2

You could add several "catch" statement into the test method for different exceptions, like:

try {
    element.createCustomer(null);

    Assert.fail("Exception was expected!");
} catch (NullPointerException _ignore) {
} catch (UnknownCustomerException _ignore) {
}

or with Java 87

try {
    element.createCustomer(null);

    Assert.fail("Exception was expected!");
} catch (NullPointerException | UnknownCustomerException _ignore) {
}

But if you switch from JUnit to TestNG, then your test will be much cleaner:

@org.testng.annotations.Test(expectedExceptions = { NullPointerException.class, UnknownCustomerException.class })
public void createCustomer() throws NullPointerException, UnknownCustomerException {
    element.createCustomer(null);
}

More information about "expectedException" is here: http://testng.org/doc/documentation-main.html and example of the usage can be found here: http://www.mkyong.com/unittest/testng-tutorial-2-expected-exception-test/

1 Comment

multicatch was already inlcuded in java 7
1

I suggest that you take a closer look at the JavaDoc of ExpectedException and implement different tests for different validations, e.g.

 public class CustomerTest {

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

     @Test
     public void throwsNullPointerExceptionForNullArg() {
        exception.expect(NullPointerException.class);

        element.createCustomer(null);
     }

     @Test
     public void throwsUnknwonCustomerExceptionForUnkownCustomer() {
        exception.expect(UnknownCustomerException.class);
        // exception.expectMessage("Some exception message"); uncomment to verify exception message

        element.createCustomer("unknownCustomerName");
     }

     @Test
     public void doesNotThrowExceptionForKnownCustomer() {

        element.createCustomer("a known customer");
        // this test pass since ExpectedException.none() defaults to no exception
     }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.