【问题标题】:JUnit 5 mock YearMonth.now but call real method for YearMonth.fromJUnit 5 模拟 YearMonth.now 但为 YearMonth.from 调用真实方法
【发布时间】:2021-04-06 10:30:23
【问题描述】:

我的用例是我使用 JUnit 5 并且需要模拟静态方法 YearMonth.now()。 为此,我使用的解决方案是:

YearMonth defaultYearMonth = YearMonth.of(DEFAULT_YEAR, Month.MARCH);
try (MockedStatic<YearMonth> mockedScope = Mockito.mockStatic(YearMonth.class)) {
    mockedScope.when(YearMonth::now).thenReturn(defaultYearMonth);
    // Rest of the code
    // StepVerifier to verify a subscription
}

现在的问题是,由于在模拟范围内模拟 YearMonth,我无法模拟所有其他方法。但我想调用YearMonth.from() 的真正方法。 为此,我尝试添加

mockedScope.when(() -> YearMonth.from(any())).thenCallRealMethod();

但这不起作用,我得到了null,其中调用了YearMonth.from(LocalDateTime)

我不确定我错过了什么。如果可能是由于模拟 YearMonth 类,有没有办法监视静态方法?如果没有任何关于如何使用 JUnit 5 实现这一点的帮助将非常有帮助。

【问题讨论】:

    标签: java unit-testing junit junit5


    【解决方案1】:

    如果您查看 Mockito.mockStatic(Class&lt;T&gt;) 的 Javadoc,您会发现所有静态方法都被模拟了,这意味着如果在您的测试范围内使用它们,您需要手动处理它们。

    为给定类或接口的所有静态方法创建一个线程本地模拟控制器。 [...]

    修复它的方法是根据 Javadoc 在您的 mockStatic 方法中使用一个额外的参数。第二个参数是defaultAnswer

    defaultAnswer – 调用静态方法时的默认答案。

    MockedStatic<YearMonth> mockedScope = Mockito.mockStatic(YearMonth.class, Mockito.CALLS_REAL_METHODS)
    

    【讨论】:

    • 感谢上述解决方案。现在我没有得到 null 但仍然不是预期的行为 YearMonth startMonth = YearMonth.from(transfersMetadata.getStartDate()); YearMonth endMonth = YearMonth.from(transfersMetadata.getEndDate()); return (int) ChronoUnit.MONTHS.between(startMonth, endMonth) + 1;我有上面的代码sn-p。虽然我应该得到 12,但它给出了 1 个月的差异
    • 您在transfersMetadata@VarunSharma 中的输入是什么?
    • @VarunSharma 我找到了,看看修改后的答案:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多