Mockito 5.16.0+ 结合Java模块系统无法mock javax.xml.parsers.DocumentBuilder的解决方法
我完全懂你遇上这个问题的头疼——用了好几年Java模块系统,Mockito升级到5.16.0+后突然没法mock JDK里的DocumentBuilder,确实闹心。从你贴的错误日志里能揪出核心问题:Mockito模块现在没法读取java.xml模块了,这是因为5.16.0版本开始Mockito引入了自己的module-info.java,从“自动模块”变成了“显式模块”,权限管控比之前严格了一大截。
下面是亲测有效的解决步骤:
1. 调整测试模块的module-info.java配置
先确保你的测试模块的模块声明里包含这几项:
// 引入Mockito依赖 requires org.mockito; // 引入JDK的java.xml模块(测试代码要用到DocumentBuilder) requires java.xml; // 把javax.xml.parsers包开放给Mockito,让它能生成该包下类的mock子类 opens javax.xml.parsers to org.mockito;
如果你的测试模块本身是open module(即声明为open module 你的测试模块名 { ... }),那opens这行可以省略——因为open模块默认允许所有模块反射访问内部包。
2. 添加JVM运行参数,给Mockito模块开放java.xml的读取权限
Mockito官方模块没声明需要读取java.xml,所以得手动给它加这个权限。不同构建工具的配置方式如下:
Maven项目
修改maven-surefire-plugin的配置,加上JVM参数:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <!-- 让org.mockito模块能读取java.xml模块 --> <argLine>--add-reads org.mockito=java.xml</argLine> </configuration> </plugin>
Gradle项目
在测试任务里添加JVM参数:
test { jvmArgs '--add-reads org.mockito=java.xml' }
3. 验证效果
做完上面两步后重新运行测试,应该就能正常创建DocumentBuilder的mock了。核心是解决了三个权限问题:
- 让测试模块能访问
java.xml模块 - 让Mockito模块能读取
java.xml模块 - 让Mockito能反射操作
javax.xml.parsers包下的类
如果还是有问题,可以尝试临时切换Mock生成方式(仅用于排查,不推荐长期使用):在src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker文件里写入mock-maker-subclass,切换到子类生成模式而非inline模式,但这种方式对某些类的mock支持有限,优先推荐前面的模块配置方案。
内容来源于stack exchange

