无法对Java代码使用Mockito或PowerMockito的反射进行单元测试
我正试图编写一个单元测试来测试这段代码,但如前所述,我在使用本机类java.lang.class时遇到了Mockito/Powermockito的限制 我如何测试这个:无法对Java代码使用Mockito或PowerMockito的反射进行单元测试,java,unit-testing,reflection,mockito,powermockito,Java,Unit Testing,Reflection,Mockito,Powermockito,我正试图编写一个单元测试来测试这段代码,但如前所述,我在使用本机类java.lang.class时遇到了Mockito/Powermockito的限制 我如何测试这个: Method[] serverStatusMethods = serverStatus.getClass().getMethods(); for (Method serverStatusMethod : serverStatusMethods) { if (serverStatusMethod.getNa
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
对象。多重责任使得测试方法变得困难。当模仿类太困难时,要做的就是:添加另一层抽象。例如,将反射操作提取到单独的方法中:
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
对象。多重责任使测试方法变得困难。谢谢你的回答,你是对的,我没有正确遵循“单一责任原则”。但用你的解决方案,我只是把问题转移到另一层。无论如何,我无法从invoke(serverStatus)
方法引发异常。您对从invoke方法引发异常不感兴趣。您感兴趣的是从resolveServerStatus中抛出异常,并验证代码的行为是否符合预期。你可以接受有些事情太复杂,价值太低,不需要花很多时间(当然,除非你因为官僚主义的原因而做代码覆盖率:)。好的,谢谢你的帮助,我总是觉得如果覆盖率不高,代码可能会被破坏,但对于这种困难的情况,我认为可以毫无问题地忽略测试。我按照你的建议解决了问题,应用了SRP。谢谢你的回答,你是对的,我没有正确遵循“单一责任原则”。但用你的解决方案,我只是把问题转移到另一层。无论如何,我无法从invoke(serverStatus)
方法引发异常。您对从invoke方法引发异常不感兴趣。您感兴趣的是从resolveServerStatus中抛出异常,并验证代码的行为是否符合预期。你可以接受有些事情太复杂,价值太低,不需要花很多时间(当然,除非你因为官僚主义的原因而做代码覆盖率:)。好的,谢谢你的帮助,我总是觉得如果覆盖率不高,代码可能会被破坏,但对于这种困难的情况,我认为可以毫无问题地忽略测试。我按照你的建议解决了问题,应用了SRP。