【问题标题】:Why mocking a private method enters method?为什么模拟私有方法进入方法?
【发布时间】:2015-06-12 14:55:32
【问题描述】:

我正在使用 PowerMockito 在我的测试中模拟一个私有方法。

validator = spy(new CommentValidator(form, request));
PowerMockito.when(
        validator,
        method(CommentValidator.class, "isCaptchaValid",
        HttpServletRequest.class))
    .withArguments(Mockito.any())
    .thenReturn(true);

当我运行测试时,我在isCaptchaValid 方法的第二行得到java.lang.reflect.InvocationTargetExceptionNullPointerException,如下所示:

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 对象。

【问题讨论】:

  • 您确定您的声明正确吗? The documents 显示不同;您应该提供实例、方法名称及其参数。
  • 嗯,我认为您发布的内容没有任何问题。但是,在模拟时需要避免一些陷阱,尤其是在模拟私有方法时。您可能需要提供一个可运行的示例(SSCCE,sscce.org)。
  • 正如@Makoto 所指出的,您应该像这样部分模拟该方法:PowerMockito.doReturn(true).when(validator, "isCaptchaValid", mockHttpServletRequest); 其中mockHttpServlcetRequest 是一个实例而不是类-对于 HttpServletRequest 你可能有看看 springs MockHttpServletRequest 类或其构建器。使用 spy 将保持方法主体完好无损,而使用 mock 通常会用 return null 替换主体 - 这就是您的调用在 request.getSession() 调用时产生 NPE 的原因
  • 诚和罗曼,请查看APIstatic <T> WithOrWithoutExpectedArguments<T> when(Class<?> cls, Method method)。我需要WithOrWithoutExpectedArguments 接口才能使用.withArguments
  • @sleske,我真的很喜欢你发送的链接。从来没有见过。然而,在我看来,我是本能地遵循了这一点。您认为我可以添加到 OP 中的具体内容是什么?也许Captcha.isInputValid 方法?我马上补充。如果还有什么可以补充的,请告诉我。

标签: java unit-testing powermockito


【解决方案1】:

问题已解决

通过调用

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 忽略方法的主体并立即返回您想要的。

【讨论】:

    猜你喜欢
    • 2019-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-03
    • 2017-03-15
    • 1970-01-01
    • 1970-01-01
    • 2014-10-15
    相关资源
    最近更新 更多