实现中用到ApplicationContextAware机制spring单元测试冲突的解决

贡献给搜索引擎~

这个问题纠结了我比较久,而且google不到答案,今天看了下spring相关部分的代码,终于解决了,所以记录一下。

先说下场景~

1.程序中有一个singleton的class实现ApplicationContextAware来获取spring支持,这里称为ss(springsupportorspringschedulerorspringsuibian……)好了。

2.单元测试依赖spring都基于AbstractDependencyInjectionSpringContextTests来玩。

3.多组单元测试跑到的代码都会用到ss来获取spring支持。

spring单元测试基类会把你所有的配置文件location字串拼起来作为key来cache一个解析好的applicationContext。

于是假设我有4个单元测试类,分为2组,1、2的配置文件是a.xml,3、4的配置文件是b.xml。我跑这4个单元测试类的时候可能会出现1-3-2-4这样的顺序(不知道排序规则是什么……)。

因为spring的cache,它只在1、3的时候会分别解析a.xml和b.xml两个配置文件并初始化ss,为ss注入applicationContext;而跑2、4的时候则是直接从cache中获取applicationContext。

这样就会导致我在跑2的时候,ss中被注入的applicationContext仍然是b.xml的(因为2并不reloadconfig,也就不会重新初始化ss和注入applicationContext),然后2的单元测试就会发现从ss中获取不到需要的bean。

这么看来,有两个解决办法。一个是让他们都用一样的配置文件,这样显然不太爽。另一个就是想办法让ss中的applicationContext和spring单元测试容器中的applicationContext同步。

解决方法其实很简单,覆盖spring单元测试基类的prepareTestInstance()方法,用this.applicationContext直接干掉ss中的applicationContext就行了……

相关推荐