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
相关产品推荐
相关产品推荐

