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

Mockito单元测试出现Unparseable date异常问题求助

问题分析与解决方案

问题描述

调用HelperFunctions.getFormattedServerDate("2024-01-05T06:00:00", "yyyy-MM-dd'T'HH:mm:ssZZZZZ")预期得到"Fri Jan 05 11:30:00 GMT+05:30 2024"。该函数通过设置时区为GMT的SimpleDateFormat解析日期,实际运行转换正常,但Mockito单元测试时抛出ParseException,异常信息为:

Unparseable date: "2024-01-05T06:00:00+00:00"

核心原因

测试环境中,传入函数的日期字符串被自动添加了时区后缀+00:00,但原解析模式yyyy-MM-dd'T'HH:mm:ssZZZZZ与带时区后缀的字符串匹配逻辑存在冲突(或测试逻辑篡改了输入参数),导致解析失败。

解决方案

方案1:修正测试参数篡改问题

检查Mockito测试代码,确认是否存在参数匹配器、间谍对象等逻辑将输入的"2024-01-05T06:00:00"修改为"2024-01-05T06:00:00+00:00"。可使用ArgumentCaptor捕获实际传入的参数,调整测试逻辑,确保输入参数与实际运行时一致。

方案2:让函数兼容带/不带时区的输入

由于SimpleDateFormat不支持可选格式,可在函数中添加容错逻辑,尝试多模式解析:

public static String getFormattedServerDate(String inputDate, String inputPattern) {
    SimpleDateFormat sdf = new SimpleDateFormat(inputPattern);
    sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
    Date date;
    try {
        date = sdf.parse(inputDate);
    } catch (ParseException e) {
        // 带时区解析失败时,尝试不带时区的模式
        String noZonePattern = inputPattern.replace("ZZZZZ", "");
        SimpleDateFormat sdfNoZone = new SimpleDateFormat(noZonePattern);
        sdfNoZone.setTimeZone(TimeZone.getTimeZone("GMT"));
        try {
            date = sdfNoZone.parse(inputDate);
        } catch (ParseException ex) {
            throw new RuntimeException("日期解析失败", ex);
        }
    }
    // 格式化目标格式
    SimpleDateFormat outputSdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
    outputSdf.setTimeZone(TimeZone.getTimeZone("GMT+05:30"));
    return outputSdf.format(date);
}

方案3:替换为Java 8+的java.time API(推荐)

SimpleDateFormat线程不安全且API老旧,java.time包支持可选格式,处理时区更灵活:

public static String getFormattedServerDate(String inputDate, String inputPattern) {
    // 构建支持可选时区的解析器
    DateTimeFormatter parser = DateTimeFormatter.ofPattern(inputPattern + "[ZZZZZ]")
            .withZone(ZoneId.of("GMT"));
    ZonedDateTime zdt = ZonedDateTime.parse(inputDate, parser);
    // 格式化目标格式
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy")
            .withZone(ZoneId.of("GMT+05:30"));
    return zdt.format(formatter);
}

该方式可同时解析带/不带时区的字符串,避免解析异常,且线程安全。


内容的提问来源于stack exchange,提问作者arun

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 23:31:27