如何模拟私有静态方法的Parse Exception?

时间:2017-05-09 15:43:46

标签: java unit-testing mockito powermockito

我有以下方法:

    public class DateValidation() {
        private static boolean isValid(String date) {
            SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
            dateFormat.setLenient(false);
            try {           
                dateFormat.parse(inDate.trim());
            }   
            catch (ParseException pe) {
                    pe.printStackTrace();
                    return false;
            }
            return true;
        }
    }

到目前为止,这是我的模拟测试:

public void testIsValidDate_Exception() throws Exception {
    PowerMockito.spy(DateValidation.class);
    PowerMockito.doThrow(new ParseException(null,0)).when(DataValidation.class, "isValidDate", "01/012017");
}

但这就是我陷入困境的地方。如何验证测试是否会引发ParseException?如果输入日期格式错误,那么应抛出ParseException,对吗?

2 个答案:

答案 0 :(得分:1)

首先,您的方法不会抛出任何异常(您正在捕获它并返回false)。那么,你如何测试它抛出ParseException。 所以你必须测试方法是否返回false,这意味着它抛出了parseException 如果你想测试抛出的异常,那么你不应该在你的方法中捕获它 其次,您的测试方法名称确实令人困惑,它会显示testIsValidDate,但您正在测试无效日期投掷异常。
就这样做

DateValidation spyDateValidation = PowerMockito.spy(DateValidation.class);        
boolean result = Whitebox.invokeMethod(spyDateValidation, "isValidDate", "01/012017");
assertFalse(result);

答案 1 :(得分:0)

DateValidation课程中,方法isValid私有,因此您无法在DateValidation课程之外调用它。要测试它,你需要在测试类中调用方法,所以首先要添加另一个调用它的方法:

public class DateValidation {

    private static boolean isValid(String date) throws ParseException {
        SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
        dateFormat.setLenient(false);
        try {
            dateFormat.parse(date.trim());
        } catch (ParseException pe) {
            pe.printStackTrace();
            return false;
        }
        return true;
    }

    // public method that calls isValid private method (so I can call it in another class)
    public static void isValidDate(String date) throws ParseException {
        DateValidation.isValid(date);
    }
}

现在,您的测试类将如下所示:

@RunWith(PowerMockRunner.class) // needed for powermock to work
// class that has static method and will be mocked must be in PrepareForTest
@PrepareForTest({ DateValidation.class }) 
public class DateValidationTest {

    // this test expects ParseException to be thrown
    @Test(expected = ParseException.class)
    public void testIsValidDate_Exception() throws Exception {
        PowerMockito.spy(DateValidation.class);
        // mock static private method
        PowerMockito.doThrow(new ParseException(null, 0)).when(DateValidation.class, "isValid", "01/012017");

        // call the public method (isValidDate) that calls mocked private method (isValid)
        DateValidation.isValidDate("01/012017");
    }
}

expected = ParseException.class是关键部分。有了这个,测试知道它必须检查ParseException(如果没有发生异常则失败)

注意:如果您希望isValid方法在无效输入的所有情况中抛出ParseException(而不仅仅是在您的测试中) ),您必须删除try/catch块,然后只需拨打dateFormat.parse

在这种情况下,您不需要模拟它,因为如果输入无效,它将始终抛出异常。无论如何,您仍然需要测试中的expected = ParseException.class来检查是否发生了异常。