Apache Commons StringSubstitutor在main正常运行但单元测试失败
问题排查与解决方案
1. Mock返回的文本格式不匹配
单元测试中用Mockito模拟WordDocumentReader返回的文本,可能占位符格式和StringSubstitutor配置的不兼容。比如代码里用${name}格式,但mock返回文本用了{{name}},或是占位符大小写、拼写不一致。
- 解决方案:
- 核对
StringSubstitutor初始化代码,确认占位符的前缀/后缀(默认是${}) - 确保mock返回的文本占位符格式完全一致,示例:
when(reader.readDocument()).thenReturn("姓名:${name},年龄:${age}");
- 核对
2. PersonPlaceholders生成的映射表异常
如果PersonPlaceholders生成的映射表为空,或是键名和文本占位符不对应(比如映射表键是username,但文本里是name),替换自然不会生效。
- 解决方案:
- 在单元测试中添加断言,验证映射表的键值对是否符合预期:
Map<String, String> placeholders = personPlaceholders.generate(person); assertThat(placeholders).containsEntry("name", "张三"); - 检查
PersonPlaceholders的逻辑,确保每个占位符都正确关联Person对象的属性。
- 在单元测试中添加断言,验证映射表的键值对是否符合预期:
3. StringSubstitutor未正确传入映射表
代码中可能错误初始化了StringSubstitutor,比如没传入生成的映射表,或是传入了空Map。
- 解决方案:
- 检查
replacePlaceholdersInText方法的实现,确认StringSubstitutor的初始化逻辑:StringSubstitutor substitutor = new StringSubstitutor(placeholders); String result = substitutor.replace(text); - 单元测试中通过调试或日志,确认传入
StringSubstitutor的Map不为空。
- 检查
4. Mock返回的文本被意外修改
如果mock的WordDocumentReader返回的文本,在传递到StringSubstitutor前被其他逻辑修改(比如转义了占位符的$符号),也会导致替换失败。
- 解决方案:
- 单元测试中,调用
replacePlaceholdersInText前先断言mock返回的文本内容:String mockText = reader.readDocument(); assertEquals("姓名:${name}", mockText); - 检查
replacePlaceholdersInText中读取文本后的处理逻辑,确保没有对占位符进行转义或修改。
- 单元测试中,调用
5. 依赖版本或环境冲突
虽然main方法正常,但单元测试环境可能引入了不同版本的Apache Commons Text依赖,导致StringSubstitutor行为不一致。
- 解决方案:
- 核对单元测试与main环境的Apache Commons Text版本,确保一致。
- 可在单元测试中打印
StringSubstitutor的版本信息,确认环境一致性。
内容的提问来源于stack exchange,提问作者AceKokuren
相关产品推荐
相关产品推荐

