领先一步
VMware 提供培训和认证,以加速您的进步。
了解更多在 Spring 上下文中对某些类进行单元测试时,我最恼火的事情之一就是使用所有依赖项初始化它们。 对于 Spring 框架扩展(如 FactoryBean 实现或 *Aware 实现)尤其如此。 添加所有依赖项很麻烦,并且很容易忘记调用 bean 生命周期方法,例如 InitializingBean 中的 afterPropertiesSet 方法。
用于单元测试的 Spring 基类提供了很大帮助,但仍然有一些事情很繁琐。 例如,在许多情况下,有必要消除自动装配的歧义,以便协作者获得正确的实现。 此外,要从生命周期执行中受益,您必须从当前配置中测试 bean 实例,这并不总是方便的。
我一直在使用一个简单的工具来简化单元测试中协作者的设置,我想我会和一些人分享它。 它提供了一个 bean 初始化器,可用于连接现有 bean 上的依赖项。
BeanInitializer 初始化一个 bean,添加依赖项,并在一个方法中执行生命周期回调
public class InitializingTests extends TestCase {
private Collaborator collaborator;
public void setUp throws Exception {
super.setUp();
collaborator = new SimpleCollaborator();
}
public void testBeanWithSimpleDependencyOnThis() throws Exception {
Service bean = BeanInitializer.initialize(new ServiceImpl(), this);
assertNotNull(bean.getCollaborator());
}
}
BeanInitializer.initialize 方法的参数是要初始化的 bean,以及要设置在其上的属性源,在此示例中为单元测试本身。 从 InitializingBean、BeanNameAware 等的生命周期回调在返回 bean 之前被调用。 这很有用,因为可以添加或删除生命周期接口,而无需更改单元测试。
你也可以这样做
Service bean = BeanInitializer.initialize(new ServiceImpl(), new Collaborator());
或者这样做
Service bean = BeanInitializer.initialize(new ServiceImpl(), new
Object[] { new Collaborator(), "valueOfOnlyStringProperty" } );
或者这样做(例如,在使用 spring-mock 基类的单元测试中)
Service bean = BeanInitializer.initialize(new ServiceImpl(),
new Collaborator(), applicationContext );
在最后一种情况下,显式协作者会覆盖 applicationContext 中具有相同接口的任何值,因此自动装配是明确的。 这非常适合添加复杂服务类的模拟实现,其中应用程序上下文已经包含“真实”实现。 请记住,Spring 单元测试基类会缓存应用程序上下文实例,因此这可能是提高单元测试效率的绝佳方法。
如果您有兴趣,我已经上传了代码(here) - 它非常简单,但非常有用,希望如此。