user3169231
user3169231

Reputation: 257

JUnit : a Successful test if an exception is catched

Is it possible for that a JUnit test succeeds if it returns the expected exception?

Can you tell me how to implements such test by a simplified example?

Thanks a lot.

Upvotes: 5

Views: 5673

Answers (3)

Raj
Raj

Reputation: 1

Test Case :

public class SimpleDateFormatExampleTest {

    @SuppressWarnings("deprecation")
    @Test(expected=ParseException.class)
    public void testConvertStringToDate() throws ParseException {
        SimpleDateFormatExample simpleDateFormatExample = new SimpleDateFormatExample();

    Assert.assertNotNull(simpleDateFormatExample.convertStringToDate("08-16-2011"));

The following will pass without (expected=ParseException.class)

Assert.assertNotNull(simpleDateFormatExample.convertStringToDate("08/16/2011"));

    }

Test Class

public class SimpleDateFormatExample {


    public Date convertStringToDate(String dateStr) throws ParseException{
        return new SimpleDateFormat("mm/DD/yyyy").parse(dateStr);
    }
}

Upvotes: 0

Itay Maman
Itay Maman

Reputation: 30733

The proper way to achieve that, in JUnit4, is to use an ExpectedException public field, annotated with @Rule, as follows:

import org.junit.rules.ExpectedException;
import org.junit.Rule;
import org.junit.Test;


public class MyTestClass {
  @Rule 
  public ExpectedException thrown = ExpectedException.none();

  @Test
  public void aTestThatSucceedsOnlyIfRuntimeExceptionIsThrown() {
      thrown.expect(RuntimeException.class);  
      // invoke code to be tested...
  }
}

Note that you also use @Test(expected=RuntimeException.class) but the former is usually considered superior for the following reason: it allows you to specify the exact point in your test where an exception should be thrown. If you use the latter the test will succeed if any line inside it throws an exception (of the expected type) which is often not what you want.

Upvotes: 3

Hrishikesh
Hrishikesh

Reputation: 2053

Why cant you just catch your exception in the test? There are different ways of doing this. Like annotating @Test(expected = DataAccessException.class) and that needs to be used on a case by case basis too. But below way is what i would propose.

public class TestCase{
    @Test
    public void method1_test_expectException () {
     try{
     // invoke the method under test...
     Assert.fail("Should have thrown an exception"); 
     // This above line would only be reached if it doesnt throw an exception thus failing your test. 
                }
     catch(<your expected exception> e){
       Assert.assertEquals(e.getcode(), somce error code);
     }
 }

A couple of benefits using this approach.

  • If you have your custom exception, with an error code, you can assert for the error code. Thus tightening your testcase.
  • Any other unexpected exception of the same type but of a different error code would fail the test. (This helps when you are in continuous development and the team keeps refactoring the code for newer requirements. The test catches it.)

Upvotes: 7

Related Questions