Assert that certain parameterized vectors will throw an exception in JUnit?

2.9k views Asked by At

I wonder how I can write test for particular exception assertion?

For example (my test data container):

@Parameters(name = "{index}: {0} > {1} > {2} > {3} > {4}")
public static Iterable<Object[]> data() {
  return Arrays.asList(new Object[][] {
    {"1200", new byte[] {0x4B0}, "1200", 16, 2},
    {"10", new byte[] {0x0A}, "10", 8, 1},
    {"13544k0", new byte[] {0x0A}, "1200", 8, 1},  <== assert thrown exception
    {"132111115516", new byte[] {0x0A}, "1200", 8, 1},<== assert thrown exception
  });
}

Is it possible to use such container data to assert exception, or I need to model situation in concrete test-method?

3

There are 3 answers

1
Paul Hicks On BEST ANSWER

Before JUnit 4.7, it wasn't possible to use data-driven testing like this, where some data combinations produce exceptions and some don't.

It is possible to create two different data-driven tests, where all the combinations in one don't produce exceptions, and all the combinations in the other do produce exceptions.

Use the @Test(expected=YourException.class) for the tests that expect exceptions, unless you need extra test logic. The expected annotation parameter isn't very powerful.

Since 4.7, there's been an @Rule that works for it. See @eee's answer for details.

0
piotrek On

don't do it. how do you know your code throws exception exactly when it should? split this data set into two sets. one that passes correctly and second that throws exceptions. and then create 2 tests - one always expecting exception and other expecting no exception

you could combine those 2 cases by adding additional parameter like @eee shown but it adds logic/complexity to your test cases and makes them less readable

0
eee On

You can use the JUnit rule ExpectedException for this, here is a runnable example:

@RunWith(Parameterized.class)
public class MyParameterizedTest {

    public class UnderTest {
        public void execute(String input) {
            if ("1".equals(input)) {
                throw new RuntimeException();
            }
        }
    }

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

    @Parameters(name = "{index}: {0}")
    public static Iterable<Object[]> data() {
        return Arrays.asList(new Object[][] {
                    {"1", RuntimeException.class},
                    {"2", null}    
        });
    }

    @Parameter(value = 0)
    public String input;

    @Parameter(value = 1)
    public Class<Throwable> exceptionClass;

    @Test
    public void test() {
        if (exceptionClass != null) {
            expected.expect(exceptionClass);
        }

        UnderTest underTest = new UnderTest();          
        underTest.execute(input);
    }
}