如何模拟私有静态方法的解析异常?
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);
在DateValidation
class中,方法isValid
是private,所以你将无法在外部调用它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
来检查异常是否发生。
我有以下方法:
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);
在DateValidation
class中,方法isValid
是private,所以你将无法在外部调用它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
来检查异常是否发生。