0

I am working one a school program that requires me to test a custom defined exceptions.

There are 5 Calculator.java files and my job is to add more cases and find which runs perfectly right.

However when I try to use Expected exception test to test the excetion, it seems that the as long as the first case works well, the program will automatically be thrown and stop there. The other cases behind //TODO will not run at all.

 /**
 * The calculate method have to return the Grade based on :
 * 
 * "lab", "ass1" and "ass2" marks are between 0 and 10 (inclusive).
 * + "final" is between 0 and 100 (inclusive).
 * 
 * If any of these components are not within the expected range 
 * then an OutOfRangeException is thrown.
 *  
 */
//Here is the interface of MarkCalculator
public interface Calculator {
    Grade calculate(int lab, int ass1, int ass2, 
                            int final, boolean attended) throws OutOfRangeException; 
}

Can someone please tell me how to prevent this from happening, thanks

@Test(expected = OutOfRangeException.class)
public void testException() throws OutOfRangeException {
    calculator.calculateMark(-1, 0, 0, 0, true);
    //TODO: write more test cases if you need


    calculator.calculateMark(100 , 0 , 0 , 0 , true);
    calculator.calculateMark(0 , 11 , 0 , 0 , true)
}
A1pine
  • 1
  • 1
  • check here ... https://stackoverflow.com/questions/156503/how-do-you-assert-that-a-certain-exception-is-thrown-in-junit-4-tests?rq=1 ... especially the parts with the `try ... catch` blocks. – second Jul 25 '19 at 05:51
  • If you want to use the annotation, you have to put each call that is supposed to fail into its own test method. Because when the exception happens the rest of the method is no longer executed. – Thilo Jul 25 '19 at 05:53

2 Answers2

1

An easier way is to extract calculation to another method in the test class itself.

private Class cauculate(int lab, int assignment1, int assignment2, int finalexam, boolean attendedFinal){
    try{
        calculator.calculateMark(lab, assignment1, assignment2, finalexam, attendedFinal);
    } catch (Exception e){
        return e.getClass();
    }
    return Void.class;
}

@Test
public void testException() {
    Assert.assertEquals(ComponentOutOfRangeException.class, calculate(-1, 0, 0, 0, true));
    Assert.assertEquals(ComponentOutOfRangeException.class, calculate(11, 0, 0, 0, true));
//....
}
GirishB
  • 134
  • 7
0

Unit testing purpose is to test 1 specific thing and that is why it doesn't support a cool handling for multiple exceptions ( as it is invalid for java itself to ignore exception without a try-catch or some other handling ) and that is why you need a workaround as the previous answer suggested.

My suggestion is to write different @test functions and name each one after what they are testing (for example test_firstParameterNull , test_secondParameterNull etc ). that way when you will finally run the tests they will be able to provide feedback on what exactly failed instead of a general "your calculator failed". And to be fair your unit tests will look like this. Only 1 of the x will change per scenario so you can copy paste it as many times as you wish and test very specific cases.

@Test(expected = ComponentOutOfRangeException.class)
public void testException() {
    calculator.calculateMark(x,x,x,x,x);
}
Michael Michailidis
  • 1,002
  • 1
  • 8
  • 21