Spring Junit 单元测试 在bean初始化前设置系统属性
背景:
已有代码,有些工厂类通过System.getProperty("xxx")来得到配置信息, 进行单元测试时想通过代码来显式设置系统属性, 而不是手工在eclispe中配置,如-Ddbconfig=/etc/config/db.config.
失败尝试一:
刚开始天真的以为只要在运行测试方法前设置系统属性即可,如下所示:
@org.junit.Before public void setUp() { System.setProperty("dbconfig", "/etc/config/db.config"); }
结果证明在进入setUp时,spring就已完成了bean的初始话了, 故在进入setUp前,就会抛出空指针异常.
失败尝试二:
想能不能在spring加载bean之前,就设置系统属性,尝试了如下的方法,
即在applicationContext一开始就设置系统属性,发现也不灵,spring加载bean时,加载上述的MethodInvokingFactoryBean bean的顺序是随机的,故有可能在加载它之前就报空指针异常了.
可以观察如下的日志输出:
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@543e710e: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,......org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
成功尝试:
最后尝试了如下的方法,可以满足要求,即程序运行一开始就添加系统属性
static { System.out.println("Set system properties..."); System.setProperty("dbconfig", "/etc/config/db.config"); }
即将添加系统属性的代码放在在测试类中的静态代码块中,这样的话运行单元测试时,便会首先执行静态代码块中的内容了.
参考文档: