BeanInitializer:在单元测试中连接依赖项

工程 | Dave Syer | 2007 年 4 月 2 日 | ...

在 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) - 它非常简单,但非常有用,希望如此。

获取 Spring 新闻通讯

通过 Spring 新闻通讯保持联系

订阅

领先一步

VMware 提供培训和认证,以加速您的进步。

了解更多

获取支持

Tanzu Spring 在一个简单的订阅中提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区中所有即将举行的活动。

查看全部