3

I need to write a JUnit test case which would test a function passing different permutations,with corresponding results.
A successful used case returns nothing ,while a failed permutation throws exception(exception type wouldnt matter).

eg. testAppleisSweetAndRed(fruit,colour,taste)
The test would invoke the following -

testAppleisSweetAndRed(orange,red,sweet)//throws exception
testAppleisSweetAndRed(apple,green,sweet)//throws exception
testAppleisSweetAndRed(apple,red,sour)//throws exception
testAppleisSweetAndRed(apple,red,sweet)//OK

If the invocations behave as expected,the test succeeds.
How would an assert trap the first 3 invocations to ensure they do raise expected exception?

IUnknown
  • 9,301
  • 15
  • 50
  • 76
  • One option is `@Test(expected = ArithmeticException.class)` (substitute your expected exception class or just use `Exception.class`). – Ole V.V. Dec 08 '16 at 04:08
  • The test involves 4 invocations - while individual invocations would raise exception - the test should not – IUnknown Dec 08 '16 at 04:11
  • @IUnknown You should break your test into 4 test cases with one assertion each. This is a best practice because otherwise one failure may hide another. – Paul Bellora Dec 08 '16 at 04:22

3 Answers3

6

If you are using JUnit 4 or later you can do it as follows. you can use the

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


this provides a lot of features which can be used to improve our JUnit tests.
If you see the below example I am testing 3 things on the exception.

  1. The Type of exception thrown
  2. The exception Message
  3. The cause of the exception


public class MyTest {

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

    ClassUnderTest testClass;

    @Before
    public void setUp() throws Exception {
        testClass = new ClassUnderTest();
    }

    @Test
    public void testAppleisSweetAndRed() throws Exception {

        exceptions.expect(Exception.class);
        exceptions.expectMessage("this is the exception message");
        exceptions.expectCause(Matchers.<Throwable>equalTo(exceptionCause));

        testClass.appleisSweetAndRed(orange,red,sweet);
    }

}
Jobin
  • 5,610
  • 5
  • 38
  • 53
  • Would that still require wrapping each of the 4 calls in the question in its own method? – Ole V.V. Dec 08 '16 at 08:36
  • 1
    a `JUnit` test method should only test one testcase. So in this it is better to have 4 `JUnit` test methods. – Jobin Dec 08 '16 at 08:43
  • I followed the same steps but my exception gets thrown and the test fails. Not sure why it's not asserting. – Balajee Ks Nov 16 '17 at 05:36
5

Tell your test method that what kind of exception your expecting form the test method. you just have to write like below syntax.

@Test(expected = Exception.class) 

It means i am expecting a Exception will be throw from the Test. you can use other exceptions as well like ArrayOutOfBound,etc..

Rahul Kumar
  • 138
  • 1
  • 11
  • This will force me to write a separate test wrapper method for each possible permutation of the function( * n functions) – IUnknown Dec 08 '16 at 04:16
  • In that case write a try catch block for each method eg"testAppleIsSweetAndRedThrowsException" and catch the respective exception in catch block then assert it.but this solution will be an workarround. – Rahul Kumar Dec 08 '16 at 04:45
0

I think the standard way when expected is not adequate or not enough is to have an auxiliary method in you test class like:

private static void testAppleIsSweetAndRedThrowsException(Fruit fruit, Colour colour, Taste taste) {
    try {
        testAppleisSweetAndRed(fruit, colour, taste);
        fail("Exception expected from " + fruit + ", " + colour + ", " + taste);
    } catch (Exception e) {
        // fine, as expected
    }
}

Now in your test you can write:

    testAppleIsSweetAndRedThrowsException(orange, red, sweet);
    testAppleIsSweetAndRedThrowsException(apple, green, sweet);
    testAppleIsSweetAndRedThrowsException(apple, red, sour);
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161