Managing checked exceptions in different JUnit tests

99封情书 提交于 2019-12-07 20:45:09

问题


I am writing a Java Unit test for one of my method. The method declaration is like this:

public int convertToInteger() throws InvalidRomanNumberException
{
    int result=0;
    BaseRomanNumeral num1, num2; 
    int i=0;
    if(!validOperation())
        throw new InvalidRomanNumberException();
}

Now I am trying to write two unit tests. One is to test if the right exception is thrown. Another one is to make sure that that the write conversion happens. This is how my test case looks

@Test
public void testRomanNumberConversion() {
    String romanValue="MCMII";
    RomanNumber num=new RomanNumber(romanValue);
    assertEquals(1903,num.convertToInteger());  
}

@Test(expected = InvalidRomanNumberException.class)
public void testInvalidRomanNumberExceptionThrown()  {
    String romanValue="MCMIIII";
    RomanNumber num=new RomanNumber(romanValue);
    num.convertToInteger(); 
}

For both these test cases I am getting an error saying Unhandled InvalidRomanNumberException. This is resolved only when I add throws InvalidRomanNumberException to each method definition. But I don't think that is the right way. Just want to check with the rest of you, what is the norm here? How should I resolve this unhandled exception message


回答1:


Since it looks like InvalidRomanNumberException is a checked exception, you have to either surround it with a try-catch or declare that the method throws InvalidRomanNumberException. JUnit or not, this is the norm.

That being said, the test case method that you expect will throw a InvalidRomanNumberException should ideally declare that it throws one since there is no point suppressing it with a try-catch as your test case will fail. On the other hand, the test case method that you expect will not throw an exception can use a try-catch around the convertToInteger method and regardless of whether an exception is thrown, this test case should have an assert on the expected result from convertToInteger method.

The end result of a JUnit test case should be whether the test passed or failed. An exception at runtime would indicate neither. A JUnit test case must not crash.




回答2:


This feels more like it should be an unchecked exception as opposed to a checked exception.

Recall the difference between the two: a checked exception is meant to be something that's reasonably recoverable from, like a missing file or a malformed URL. An unchecked/run time exception is meant to be something that is irrecoverable, like dividing by zero.

If a user enters in an invalid Roman numeral, it might not make sense to say that they can recover and try again - the conversion layer shouldn't be responsible for that. It sounds more like a thing should be decided at instantiation time.

If you instead make your custom exception extend RuntimeException, then you won't need to declare it to be thrown (and if you did, it wouldn't have any effect), and you won't have to deal with it in your tests.

The alternative would be to declare it to be thrown in your tests instead. This has the advantage of allowing you to keep these exceptions as checked and ensuring that the tests won't complain about you not handling the potential exception from being uncaught or unthrown.

@Test
public void testRomanNumberConversion() throws InvalidRomanNumberException {
    String romanValue = "MCMII";
    RomanNumber num = new RomanNumber(romanValue);
    assertEquals(1903, num.convertToInteger());  
}

@Test(expected = InvalidRomanNumberException.class)
public void testInvalidRomanNumberExceptionThrown() throws InvalidRomanNumberException {
    String romanValue = "MCMIIII";
    RomanNumber num = new RomanNumber(romanValue);
    num.convertToInteger(); 
}


来源:https://stackoverflow.com/questions/29983716/managing-checked-exceptions-in-different-junit-tests

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!