Java 为什么模仿私有方法会进入方法?
我在测试中使用PowerMockito模拟私有方法Java 为什么模仿私有方法会进入方法?,java,unit-testing,powermockito,Java,Unit Testing,Powermockito,我在测试中使用PowerMockito模拟私有方法 validator = spy(new CommentValidator(form, request)); PowerMockito.when( validator, method(CommentValidator.class, "isCaptchaValid", HttpServletRequest.class)) .withArguments(Mockito.any()) .t
validator = spy(new CommentValidator(form, request));
PowerMockito.when(
validator,
method(CommentValidator.class, "isCaptchaValid",
HttpServletRequest.class))
.withArguments(Mockito.any())
.thenReturn(true);
当我运行测试时,我得到java.lang.reflect.InvocationTargetException
,在isCaptchaValid
方法的第二行有一个NullPointerException
,如下所示:
private boolean isCaptchaValid(HttpServletRequest request) {
Captcha captcha =
(Captcha) request.getSession().getAttribute("attribute");
if (captcha == null) {
log.debug(String.format("O valor do captcha da sessão esta nulo. IP: [%s]",
IPUtil.getReaderIp(request)));
return false;
}
if (captcha.isInputValid(
request.getParameter("captcha").toString().toUpperCase())) {
return true;
}
return false;
}
public final Boolean isInputValid(String pInput) {
if (getPuzzle() == null) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("puzzle is null and invalid. Will return Boolean.FALSE");
}
return Boolean.FALSE;
}
Boolean returnValue = verifyInput(pInput);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Validation of puzzle: " + returnValue);
}
disposePuzzle();
return returnValue;
}
如果我在模仿它的行为,为什么要考虑该方法的实现?有没有办法避免这种情况?我需要模拟它的原因是因为我无法提供
Captcha
对象。问题已解决
打电话
PowerMockito.when(
validator,
method(CommentValidator.class, "isCaptchaValid",
HttpServletRequest.class))
.withArguments(Mockito.any())
.thenReturn(true);
首先,该方法本身由PowerMockito
验证,因此很可能找到NPE
为了避免这种情况,您需要颠倒这种逻辑
doReturn(true).when(validator, "isCaptchaValid", any(HttpServletRequest.class));
它使
PowerMockito
忽略方法的主体并立即返回所需内容。您确定声明正确吗?表现不同;您应该提供实例、方法名及其参数。嗯,我看不出您发布的内容有任何错误。但是,在模拟时,尤其是在模拟私有方法时,需要避免一些陷阱。您可能需要提供一个可运行的示例(SSCCE,)。正如@Makoto所指出的,您应该像这样部分地模拟该方法:PowerMockito.doReturn(true)
其中,MockHttpServletRequest
是一个实例,而不是类-对于HttpServletRequest,您可以查看springsMockHttpServletRequest
类或其生成器。使用spy
将保持方法主体完好无损,而使用mock
通常将主体替换为返回null
-这就是调用在请求时生成NPE的原因。getSession()
调用Makoto和Roman,请检查<代码>静态,有或无预期参数(类cls,方法)。我需要带或不带预期参数的界面才能使用。带参数的@sleske,我非常喜欢你发送的链接。我从没见过。然而,在我看来,这是我的本能。你认为我能给OP增加什么?可能是Captcha.isInputValid
方法?我马上加上去。如果还有什么需要补充的,请告诉我。