Mock调用CalenderBuilder.build抛ParsingException异常求助
单元测试CalendarBuilder解析异常排查方案
核心排查方向
按优先级从高到低排查以下问题:
- Mock逻辑完全失效是最高发原因
- Mock语法写错:你写的
when(multipart.getInputStream().thenReturn(in);缺少闭合括号,正确Mockito写法为when(multipart.getInputStream()).thenReturn(in);,语法错误会导致Mock规则不生效。 - 传入参数和Mock对象不匹配:你定义的Mock变量名为
multipart,但调用业务方法时传入的是multipartFile,两个不是同一个实例,业务方法拿到的是未初始化的Mock对象,调用getInputStream()会返回null,直接触发解析异常。 - 缺少Mock初始化逻辑:
@Mock注解需要搭配测试类上的@ExtendWith(MockitoExtension.class)(JUnit5环境)或者测试方法前的MockitoAnnotations.openMocks(this)执行初始化,否则注解标记的对象就是null,调用直接空指针。
- Mock语法写错:你写的
- 测试输入流内容不符合解析规则
- 转义字符错误:你构造测试字符串用了
"2000,1,MONDAY\\n",Java中双反斜杠加n会被解析为字面量\n两个字符,不是真实的换行符。如果CalendarBuilder.build()要求按行解析日历数据,没有真实换行会直接判定格式非法抛异常,正确写法应该是"2000,1,MONDAY\n",只写一个反斜杠。 - 内容格式不匹配:先确认
CalendarBuilder要求的输入格式,比如是否要求固定的CSV表头、日期字段是否要补零、星期字段是否要求数字枚举值、是否需要指定时区/编码,你当前构造的内容如果和规则不匹配,哪怕流是对的也会解析失败。
- 转义字符错误:你构造测试字符串用了
- 流状态异常
如果你构造的ByteArrayInputStream在传入build方法前被其他逻辑读取过,流指针会停在末尾位置,build方法读取时拿到的是空内容,也会抛解析异常。可以在调用build前执行in.reset()把指针重置到起始位置,或者重新构造一个全新的输入流传入。 - 代码拼写错误
你贴的代码里存在多处拼写偏差:MulitpartFile正确拼写为MultipartFile、CalenderBuilder正确拼写为CalendarBuilder,如果实际代码里就是这么写的,会出现类不匹配、方法找不到的问题,也可能间接触发解析报错。
修正后的参考代码
// JUnit5 测试类需要加这个注解初始化Mock // @ExtendWith(MockitoExtension.class) public class XyzTest { @Mock private MultipartFile multipart; // 被测业务实例,自行按你的项目情况注入 @InjectMocks private Xyz xyz; @Test public void filexyzTest() throws Exception { // 1. 构造符合解析规则的测试内容,修正换行转义 String testContent = "2000,1,MONDAY\n"; InputStream in = new ByteArrayInputStream(testContent.getBytes(StandardCharsets.UTF_8)); // 2. 修正Mock语法,正确设置返回值 when(multipart.getInputStream()).thenReturn(in); // 3. 传入和Mock一致的对象实例 xyz.filexyz(new HashMap(), multipart); // 加你的断言逻辑 } } // 业务方法修正拼写、流关闭逻辑 public int filexyz(Map map, MultipartFile file) { // 用try-with-resources自动关闭流 try (InputStream in = file.getInputStream()) { CalendarBuilder builder = new CalendarBuilder(); Calendar calendar = builder.build(in); // 你的后续业务逻辑 return 0; } catch (IOException | ParserException e) { throw new RuntimeException("日历解析失败", e); } }
快速验证技巧
可以先跳过Mock层,直接写最小验证代码:把你构造的测试输入流直接传给CalendarBuilder.build(),如果这一步就抛异常,说明是输入内容和Builder解析规则不匹配,直接对照Builder的解析要求调整内容即可,不用在Mock逻辑上浪费时间。
内容的提问来源于stack exchange,提问作者Surendra Oraon
相关产品推荐
相关产品推荐

