如何模拟私有静态方法的解析异常?

How to mock Parse Exception for a private static method?

我有以下方法:

    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,对吧?

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

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

DateValidationclass中,方法isValidprivate,所以你将无法在外部调用它DateValidation class。而要测试它,你需要调用测试内部的方法class,所以首先要添加另一个调用它的方法:

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);
    }
}

现在,您的测试 class 将是这样的:

@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 来检查异常是否发生。