如何Mock java.nio.file下的Files API?遇空指针问题求助
解决Java NIO静态方法Mock的空指针问题
问题根源
- 缺少PowerMock核心配置:测试类未添加PowerMock运行器和需要Mock的静态类声明,导致
mockStatic未生效,实际调用了Paths.get的真实方法,触发WindowsPathParser的空指针异常。 - 方法签名不匹配:业务代码调用的是
Paths.get(String)重载方法,但测试中Mock的是Paths.get(URI)版本,Mock规则未命中,真实方法被执行。
修正后的测试代码
@RunWith(PowerMockRunner.class) @PrepareForTest({Paths.class, Files.class}) // 指定需要Mock的静态类 public class SomeTest { private Path mockPath; @ClassRule public static final TemporaryFolder testdata = new TemporaryFolder(); @Before public void setup() throws IOException { PowerMockito.mockStatic(Paths.class); PowerMockito.mockStatic(Files.class); mockPath = Mockito.mock(Path.class); } @Test public void testAbRequestAuditTasklet() throws Exception { String testFilePath = "test-sample.txt"; // 模拟业务代码传入的文件路径 Answer<Stream<String>> streamAnswer = invocation -> Stream.of("表头行", "数据行1", "数据行2"); // 对应skip(1)后计数为2 // Mock Paths.get(String)方法,匹配任意字符串参数 PowerMockito.when(Paths.get(Mockito.anyString())).thenReturn(mockPath); // Mock Files.size方法 PowerMockito.when(Files.size(Mockito.any(Path.class))).thenReturn(5000L); // Mock Files.lines方法 PowerMockito.when(Files.lines(Mockito.any(Path.class), Mockito.any(Charset.class))).thenAnswer(streamAnswer); // 此处调用你的业务逻辑代码 // 例如:YourService.processFile(testFilePath); // 验证结果(示例) // Assert.assertEquals(2, recordCount); // Assert.assertEquals(5000L, sizeInBytes); } }
关键修正点
- 新增
@RunWith(PowerMockRunner.class)和@PrepareForTest注解,确保PowerMock能拦截静态方法调用。 - 匹配正确的
Paths.get重载方法:业务代码用String参数,测试中就MockPaths.get(String)而非URI版本。 - 使用
Mockito.anyString()、Mockito.any(Path.class)等通用匹配器,避免硬编码参数导致Mock规则失效。
额外注意事项
- 若业务代码中
filePath是固定值,可改用Mockito.eq("固定路径字符串")做精准匹配。 - Mock返回的
Stream要符合业务逻辑,比如包含表头行,对应代码中skip(1)的处理逻辑。 - 业务代码的
try-with-resources已保证流关闭,测试中无需额外处理Mock的Stream。
内容的提问来源于stack exchange,提问作者PAA
相关产品推荐
相关产品推荐

