无法单元测试 Java 代码使用 Mockito 或 PowerMockito 的反射
Cannot unit test Java code uses reflection with Mockito nor PowerMockito
我正在尝试编写一个单元测试来测试这段代码,但我遇到了 Mockito/Powermockito 本机 class java.lang.Class 的限制,如 所述.
我如何测试这个:
Method[] serverStatusMethods = serverStatus.getClass().getMethods();
for (Method serverStatusMethod : serverStatusMethods) {
if (serverStatusMethod.getName().equalsIgnoreCase("get" + field)) {
serverStatusMethod.setAccessible(true);
try {
Number value = (Number) serverStatusMethod.invoke(serverStatus);
response = new DataResponse(field + " value", value);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
Logger.getLogger(StatusServlet.class.getName()).log(Level.SEVERE, null, ex);
response = new ErrorResponse(HttpStatus.Code.INTERNAL_SERVER_ERROR, ex);
}
break;
}
}
在测试用例中故意抛出此异常:
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
Logger.getLogger(StatusServlet.class.getName()).log(Level.SEVERE, null, ex);
response = new ErrorResponse(HttpStatus.Code.INTERNAL_SERVER_ERROR, ex);
}
当模拟一个 class 太困难时就做你做的事:添加另一层抽象。例如。将反射操作提取到单独的方法中:
public Number resolveServerStatus(Object serverStatus)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException {
Method[] serverStatusMethods = serverStatus.getClass().getMethods();
for (Method serverStatusMethod : serverStatusMethods) {
if (serverStatusMethod.getName().equalsIgnoreCase("get" + field)) {
serverStatusMethod.setAccessible(true);
return (Number) serverStatusMethod.invoke(serverStatus);
}
}
}
现在模拟 resolveServerStatus
方法。
如果您遵循 single responsibility principle,这就是您首先应该做的。您的方法有两个职责:解析状态编号并将其转换为 DataResponse
对象。多重职责使得测试方法变得困难。
我正在尝试编写一个单元测试来测试这段代码,但我遇到了 Mockito/Powermockito 本机 class java.lang.Class 的限制,如
我如何测试这个:
Method[] serverStatusMethods = serverStatus.getClass().getMethods();
for (Method serverStatusMethod : serverStatusMethods) {
if (serverStatusMethod.getName().equalsIgnoreCase("get" + field)) {
serverStatusMethod.setAccessible(true);
try {
Number value = (Number) serverStatusMethod.invoke(serverStatus);
response = new DataResponse(field + " value", value);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
Logger.getLogger(StatusServlet.class.getName()).log(Level.SEVERE, null, ex);
response = new ErrorResponse(HttpStatus.Code.INTERNAL_SERVER_ERROR, ex);
}
break;
}
}
在测试用例中故意抛出此异常:
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
Logger.getLogger(StatusServlet.class.getName()).log(Level.SEVERE, null, ex);
response = new ErrorResponse(HttpStatus.Code.INTERNAL_SERVER_ERROR, ex);
}
当模拟一个 class 太困难时就做你做的事:添加另一层抽象。例如。将反射操作提取到单独的方法中:
public Number resolveServerStatus(Object serverStatus)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException {
Method[] serverStatusMethods = serverStatus.getClass().getMethods();
for (Method serverStatusMethod : serverStatusMethods) {
if (serverStatusMethod.getName().equalsIgnoreCase("get" + field)) {
serverStatusMethod.setAccessible(true);
return (Number) serverStatusMethod.invoke(serverStatus);
}
}
}
现在模拟 resolveServerStatus
方法。
如果您遵循 single responsibility principle,这就是您首先应该做的。您的方法有两个职责:解析状态编号并将其转换为 DataResponse
对象。多重职责使得测试方法变得困难。