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,以及一個用於在其上設定屬性的源,在本例中是單元測試本身。在返回 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 中的同類介面的任何值,因此自動裝配是明確的。這對於新增一個複雜服務類的模擬實現非常有用,而 applicationContext 中已經包含了“真實”的實現。請記住,Spring 單元測試基礎類會快取 applicationContext 例項,因此這可以成為提高單元測試效率的一個非常好的方法。

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

獲取 Spring 新聞通訊

透過 Spring 新聞通訊保持聯絡

訂閱

領先一步

VMware 提供培訓和認證,助您加速進步。

瞭解更多

獲得支援

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位制檔案,只需一份簡單的訂閱。

瞭解更多

即將舉行的活動

檢視 Spring 社群所有即將舉行的活動。

檢視所有