You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单元测试遇InvalidUseOfMatchersException及空指针问题求助

问题分析与解决方案

第一个错误:InvalidUseOfMatchersException

原因

  1. 混合使用参数匹配器与具体值:你对nonSettle方法设置返回值时,同时用了Mockito.any(LocalDate.class)(参数匹配器)和LocalDate.of(2021,12,24)(具体参数),Mockito禁止这种混合写法,要么全用匹配器,要么全用具体值。
  2. 未使用Spy mock类内部方法:@InjectMocks创建的是真实对象,不能直接用Mockito.when()来mock它的方法,必须用@Spy包装真实对象才能实现类内部方法的mock。

解决方案

  1. 将@InjectMocks替换为@Spy并初始化真实对象:
@Spy
private CalculateDateService tested = new CalculateDateService();
  1. 用doReturn替代when(避免触发真实方法执行),先设置默认规则,再覆盖特定日期:
// 所有日期默认返回false(非结算日)
doReturn(false).when(tested).nonSettle(Mockito.any(LocalDate.class));
// 特定日期2021-12-24返回true(结算日)
doReturn(true).when(tested).nonSettle(LocalDate.of(2021, 12, 24));

第二个错误:NullPointerException

原因

你用@InjectMocks的真实对象调用Mockito.when(tested.nonSettle(...))时,会先执行真实的nonSettle方法。如果测试环境中LocalDate.now()被意外mock为null,或是因未用Spy导致真实方法执行时触发了未预期的逻辑,就会在LocalDate.of(year, 12, 24)行抛出NPE。

解决方案

  1. 采用上面的@Spy + doReturn写法,直接设置返回值,跳过真实方法的执行,从根源避免NPE。
  2. 如果需要测试真实的nonSettle逻辑,可通过PowerMock固定LocalDate.now()的返回值(需引入PowerMock依赖):
PowerMockito.mockStatic(LocalDate.class);
Mockito.when(LocalDate.now()).thenReturn(LocalDate.of(2021, 1, 1));

完整测试代码示例

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;

import java.time.LocalDate;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.any;

@RunWith(MockitoJUnitRunner.class)
public class CalculateDateServiceTest {

    @Spy
    private CalculateDateService tested = new CalculateDateService();

    @Test
    public void testRollDays() {
        // 设置默认规则
        doReturn(false).when(tested).nonSettle(any(LocalDate.class));
        // 覆盖特定日期规则
        doReturn(true).when(tested).nonSettle(LocalDate.of(2021, 12, 24));

        // 注意补全rollDays方法的第三个参数
        LocalDate result = tested.rollDays(2, LocalDate.of(2021, 12, 22), "mar");
        LocalDate correctRolledDate = LocalDate.of(2021, 12, 25);
        assertEquals(result, correctRolledDate);
    }
}

内容的提问来源于stack exchange,提问作者w97802

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 00:31:15