java - 无法对 Java 代码使用 Mockito 或 PowerMockito 的反射进行单元测试
问题描述
我正在尝试编写一个单元测试来测试这段代码,但是我遇到了本地类 java.lang.Class 的 Mockito/Powermockito 限制,如此处所述。
我怎么能测试这个:
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);
}
解决方案
每当模拟一个类太困难时,做你所做的:添加另一层抽象。例如,将反射操作提取到一个单独的方法中:
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
方法。
如果您遵循单一责任原则,这就是您首先应该做的事情。您的方法有两个职责:解析状态编号并将其转换为DataResponse
对象。多重责任使测试该方法变得困难。
推荐阅读
- ios - 正在调用 CollectionView `DidSelect` 方法但没有推送下一个 VC,如何解决?
- artifactory - 由于分割违规导致的人工崩溃
- reactjs - 自动完成悬停未正确响应
- sql - 是“从 MY_TABLE 中选择字段名、字段名;” 对任何 SQL 数据库都有效吗?
- python - 如何使我的文本不被 [''] 包围?
- sql - SQL ORACLE - “表或视图不存在”
- azure - 水平扩展/横向扩展对 Azure 应用服务定价的影响
- c++ - 模板中的类型名和变量
- scala - Scala 3 中枚举的不变默认类型
- r - 将 R 中的大型列表导出为 .txt 或 .csv