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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 11:48:23