Mockito对同一类同时用mockStatic和@InjectMocks时静态方法返回null
问题根因
- 参数匹配未命中:Mockito的
anyString()匹配器仅支持匹配非null的字符串参数,测试环境下System.getEnv("host")、System.getEnv("port")返回null,导致你对buildURI的打桩规则没有触发,未打桩的静态方法默认返回null,直接导致HttpRequest构造失败。 - 静态mock策略不合理:直接调用
mockStatic(MainClass.class)时,Mockito默认采用RETURNS_DEFAULTS策略,所有未显式打桩的静态方法都会返回默认值(引用类型为null),容易误伤类内其他静态方法。 - 代码存在笔误:
sendRequest方法中调用的方法名为buildUri(首字母u小写),但定义的静态方法名为buildURI(首字母U大写),需先统一方法名,否则无法编译通过。
修复方案
- 调整静态mock的默认策略,指定未打桩的静态方法调用真实实现:
@BeforeEach void setUp() { systemMock = mockStatic(MainClass.class, Mockito.CALLS_REAL_METHODS); }
- 修改
buildURI的打桩规则,使用支持null入参的匹配器:
// 允许入参为null的字符串类型 systemMock.when(() -> MainClass.buildURI( nullable(String.class), nullable(String.class) )).thenReturn(URI.create("http://host.com/path")); // 不需要校验参数类型时也可以直接用any()匹配所有入参 // systemMock.when(() -> MainClass.buildURI(any(), any())).thenReturn(URI.create("http://host.com/path"));
可选替代方案(无需mock静态方法)
如果希望更贴近真实执行逻辑,也可以在测试执行前后临时设置/清理环境变量,绕开null参数报错的问题:
@BeforeEach void setUp() { System.setProperty("host", "test-host"); System.setProperty("port", "8080"); } @AfterEach void tearDown() { System.clearProperty("host"); System.clearProperty("port"); }
内容的提问来源于stack exchange,提问作者Dariell Bowo
相关产品推荐
相关产品推荐

