0


spring 单元测试为 logback 添加环境变量

场景描述

spring 项目中配置了 logback 收集日志,同时使用 @SpringBootTest 做单元测试。此时就报错了,文件找不见。

ERROR in ch.qos.logback.core.rolling.RollingFileAppender[file] - Failed to create parent directories for [/home/zhu/app/logs/2022-09-07.log]
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[file] - openFile(null,true) call failed. java.io.FileNotFoundException: /home/zhu/app/logs/2022-09-07.log (No such file or directory)


原因

logback-spring.xml

文件中这么写的,bosc.rec.logSavePath 指定保存日志文件,可以在

application.yml

指定。

<?xml version="1.0" encoding="UTF-8"?><configurationscan="false"packagingData="true"><springPropertyscope="context"name="LOG_HOME"source="bosc.rec.logSavePath"/><!-- 中间内容省略了 --></configuration>
# application.ymlbosc:rec:logSavePath: ${LOG_SAVE_PATH:/home/zhu/app/logs}

当单元测试启动时先加载 logback 的配置,再执行测试 case。日志文件找不到,就会抛出上面的异常。而且使用

@Before

,

@BeforeAll

或者

static

方法,在内部

System.setProperty()

设置环境变量的方式也都不能解决问题。因为这些方法的执行都晚于 logback 配置的加载。


解决办法

直接上代码。

publicclassPropertyExtensionimplementsBeforeAllCallback{@OverridepublicvoidbeforeAll(ExtensionContext context){System.setProperty("LOG_SAVE_PATH","/Users/mac/Downloads/bosc/logs");}}
@ExtendWith(PropertyExtension.class)@SpringBootTest(classes =JobManageApplication.class)classScenePipelineRepositoryImplTest{@AutowiredScenePipelineRepository repository;@Testpublicvoidsave_ScenePipeline_succeed(){// 内容省略}

啰嗦几句

之所以抛出异常是因为使用 @SpringBootTest 做单元测试,这个注解会在执行测试 case 时会启动整个 spring 服务,所以会执行 spring 的初始化过程,加载一大堆的东西,从而包括了 logback 这玩意。

但这样使用是不合理的:

原因一:单测只测一个功能点,有必要把整个服务都启动吗?又不是做集成测试。

原因二:假如服务中有定时任务 或者 向其他服务发请求的功能,那么这个任务也会运行,这是单测不想看到的现象。

@SpringBootTest 适合做集成测试,测试成功后采用 @ignore 将测试类注解掉。

spring 三层结构,每层都有单测,每层测试的目的和方式都不一样。

曾今写过的一篇单测博客

要让团队成员都遵守一些规矩还是有些挑战的。


本文转载自: https://blog.csdn.net/yy_diego/article/details/126743074
版权归原作者 骑着蜗牛向前跑 所有, 如有侵权,请联系我们删除。

“spring 单元测试为 logback 添加环境变量”的评论:

还没有评论