Java 为什么模仿私有方法会进入方法?

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

我在测试中使用PowerMockito模拟私有方法

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,您可以查看springs
MockHttpServletRequest
类或其生成器。使用
spy
将保持方法主体完好无损,而使用
mock
通常将主体替换为
返回null
-这就是调用在
请求时生成NPE的原因。getSession()
调用Makoto和Roman,请检查<代码>静态,有或无预期参数(类cls,方法)。我需要
带或不带预期参数的界面才能使用
。带参数的@sleske,我非常喜欢你发送的链接。我从没见过。然而,在我看来,这是我的本能。你认为我能给OP增加什么?可能是
Captcha.isInputValid
方法?我马上加上去。如果还有什么需要补充的,请告诉我。