BeanInitializer:在單元測試中注入依賴項

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

在使用 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,以及要設置在其上的屬性來源,在本例中是單元測試本身。 在返回 bean 之前,會調用來自 InitializingBean、BeanNameAware 等的生命週期回調。 這很有用,因為可以添加或刪除生命週期介面,而無需更改單元測試。

您也可以這樣做


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 中具有相同介面的任何值,因此自動注入是明確的。 這非常適合添加複雜服務類別的 mock 實現,其中應用程式容器已經包含「真實」實現。 請記住,Spring 單元測試基礎類別會快取應用程式容器實例,因此這可能是提高單元測試效率的好方法。

如果您有興趣,我已上傳了程式碼 (這裡) - 它非常簡單,但希望非常有用。

取得 Spring 電子報

隨時關注 Spring 電子報

訂閱

取得領先

VMware 提供培訓和認證,以加速您的進度。

了解更多

取得支援

Tanzu Spring 在一個簡單的訂閱中提供對 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位檔案。

了解更多

即將舉行的活動

查看 Spring 社群中所有即將舉行的活動。

查看全部