MockitoJUnitRunner中Files.exists()方法失效问题排查
问题解决:Mockito测试中父类加载JSON文件失败
问题根源
- 工作目录差异:JUnit测试运行时的
user.dir是项目根目录,你写的FILE_NAME以/开头,拼接后路径变成项目根/subscription/src/test/jsonObject.json,和实际文件路径不匹配;而main方法运行时的工作目录可能是模块根目录,所以路径能正确匹配。 - 冗余实例化:测试类已经继承了
BaseTest,却手动new了新的BaseTest实例,导致当前测试类的jsonObject字段未被初始化,后续调用this.jsonObject.get()会触发空指针。 - 硬编码路径不可靠:依赖
user.dir的方式适配性差,IDE、命令行、CI等不同运行环境的工作目录可能不一致。
修复方案
方案1:用类加载器加载测试资源(推荐)
将JSON文件放到src/test/resources目录下(Maven/Gradle标准测试资源目录),通过类加载器读取,彻底摆脱对工作目录的依赖:
// 修改父类BaseTest @Slf4j public class BaseTest { public JsonObject jsonObject; // 资源路径:放在src/test/resources下直接写文件名,子目录则写如json/jsonObject.json private static String RESOURCE_NAME = "jsonObject.json"; public JsonObject initialize() { try { // 类加载器读取资源,不受工作目录影响 InputStream inputStream = getClass().getClassLoader().getResourceAsStream(RESOURCE_NAME); if (inputStream == null) { log.error("测试资源文件未找到: {}", RESOURCE_NAME); return null; } JsonParser parser = new JsonParser(); JsonReader reader = new JsonReader(new InputStreamReader(inputStream)); this.jsonObject = parser.parse(reader).getAsJsonObject(); return jsonObject; } catch (IOException e) { log.error("加载JSON资源文件失败", e); } return null; } }
方案2:修正路径拼接逻辑(仅适配固定目录结构)
若坚持用文件路径,去掉FILE_NAME开头的/,并修正测试类的调用逻辑:
// 修改BaseTest的FILE_NAME private static String FILE_NAME = "subscription/src/test/jsonObject.json"; // 移除开头的/ // 测试类中直接调用当前实例的initialize方法 @Test public void testPreNotifyService() { // 无需new BaseTest,直接用当前继承的实例 JsonElement jsonElement = this.initialize(); if (jsonElement == null) { Assert.fail("JSON测试数据加载失败"); } JsonElement element = this.jsonObject.get("contract_with_active_status"); SubscriptionContractv2 subscriptionContractv2 = new Gson().fromJson(element, SubscriptionContractv2.class); String subsPaymode = subscriptionContractv2.getSubsPaymentMode(); // 后续测试逻辑 }
额外注意事项
- 测试类继承
BaseTest后,直接用this调用方法即可,不要手动实例化新的BaseTest,否则当前测试类的成员变量无法被赋值。 - 建议添加断言判断资源是否加载成功,提前暴露问题,避免后续空指针异常。
内容的提问来源于stack exchange,提问作者user591
相关产品推荐
相关产品推荐

