无需Mock,如何触发JsonProcessingException分支的单元测试?
如何触发Jackson的JsonProcessingException分支(无需Mock)
需求目标
希望编写无需Mock的单元测试用例,测试目标方法的JsonProcessingException分支。目标第三方库代码如下:
public MyPojo question(String jsonString) { try { return objectMapper.readValue(jsonString, MyPojo.class); } catch (UnrecognizedPropertyException e) { LOGGER.error("Unrecognized property from {}", jsonString); throw new RuntimeException(e); } catch (JsonParseException | JsonMappingException e) { LOGGER.warn("Input malformed"); throw new RuntimeException(e); } catch (JsonProcessingException e) { LOGGER.error("How to get here? ={}", jsonString); throw new CustomRuntimeExeption(e); } }
该代码无法修改。
已尝试方案
- 输入
{"unknown_property": "value"},触发了UnrecognizedPropertyException分支; - 输入
{"unknown_property": "val,触发了JsonParseException分支;
均未达到目标分支。
具体问题
基于Jackson 2.15.2的异常层级:
JsonProcessingException ├── StreamWriteException │ └── JsonGenerationException - ├── StreamReadException │ ├── JsonParseException + │ │ └── (...) │ ├── InputCoercionException - ├── DatabindException │ └── JsonMappingException + │ └── (...) └── StreamConstraintsException -
(+:已触发异常;-:未触发异常)
需触发InputCoercionException或StreamConstraintsException(JsonGenerationException为JSON写入时抛出,读操作不会触发),以进入JsonProcessingException分支。
解决方案
1. 触发InputCoercionException
假设MyPojo包含数值类型字段(例如private int age;),传入无法强制转换为该类型的JSON值:
{"age": "非数字字符串"}
Jackson 2.15+会将这种类型不匹配的强制转换异常归类为InputCoercionException,它属于StreamReadException但不在已捕获的JsonParseException范围内,因此会进入目标JsonProcessingException分支。
2. 触发StreamConstraintsException
构造超出Jackson默认流约束的JSON内容,例如超长字符串值:
{"content": "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz...[重复至超过2000000字符]"}
Jackson默认限制单个字符串的长度为2000000字符,超出该限制会抛出StreamConstraintsException,它直接继承自JsonProcessingException,会落入目标分支。
内容的提问来源于stack exchange,提问作者PatPanda
相关产品推荐
相关产品推荐

