2017-04-13 63 views
0

我試圖單元測試一個類;爲了簡潔起見,我們將其稱爲Apple。它有一個需要AppleManager bean的@Required setter。 AppleManager本身具有@Required setter,而不是AppleStorageClient bean。我嘲笑AppleManager並注入到蘋果,但我也需要使用真正 AppleManager類檢索使用其AppleStorageClient對象方法的數據。我如何通過Spring/Mockito實現這一目標?在Mockito單元測試中使用帶@Required字段的類

測試:

public class AppleTest { 

    @InjectMocks 
    private Apple apple; 

    @Mock 
    private AppleManager appleManager; 

    ????? 
    private AppleManager realAppleManager; 
    //I tried = new AppleManager() here but the object is null... 
    //ostensibly because Spring doesn't know I want to use the bean 
    //also tried @Autowired to no avail 

    @Before 
    public void doBeforeStuff() { 
     MockitoAnnotations.initMocks(this); 
    } 

    ... 
} 

來源:

public class Apple { 

    private AppleManager appleManager; 

    @Required 
    public void setAppleManager(AppleManager appleManager) { 
     this.appleManager = appleManager; 
    } 

    .... 

} 

&

public class AppleManager { 

    private AppleStorageClient appleStorageClient; 

     @Required 
     public void setAppleStorageClient() { 
      this.appleStorageClient = appleStorageClient; 
     } 

     ... 

    } 

回答

3

一般來說它看上去就像是 'uncomplete' 在這裏。我會解釋爲什麼。

技術上如果你使用Spring - 它聽起來並不像一個單元測試來我了,可能是集成測試什麼的。 單元測試通常應該真的非常快,並且啓動Spring不會讓它們通過足夠快的速度(想想在您的項目中有數千個單元測試,每個單元測試在啓動時都會運行在彈簧上 - 這將花費他們很長時間才能完成)。

但是,讓我們說,它大約只有定義。當你用JUnit使用spring測試框架時,有人必須啓動並維護一個spring context來完成所有的依賴注入魔術並將其應用到測試用例。 JUnit中實現一個特殊的亞軍(JUnit的抽象)是必需的:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration({ "classpath:my-test-context.xml" }) // or use Java Config 

這不會出現在這個問題雖然。

因此,現在春天創建一個上下文,並將嘗試注入豆。我們已經有效地將我們的問題簡化爲有兩個接口實現的問題,並要求Spring通過接口注入實現,以便注入兩個不同的實現。有兩種解決方案我可以在這裏看到:

  1. 創建一個模擬外部春天 - 你可能不會在春天指定你的期望。僅維持一個「真正的蘋果經理」春

  2. 無論是在春季,但在你的測試用例使用@Qualifier註釋

現在,我想強調的是什麼維護,如果你保持真正的蘋果經理聯繫「蘋果商店」(可能是一個數據庫,有驅動程序支持,事務管理等),你必須創建一個測試環境,以便它能夠連接到該數據庫,並且如果蘋果管理器在內部注入它的通過spring的依賴關係,那麼這些bean也必須被指定。 因此,如果將來你會改變底層存儲中的某些東西(比如說,在一個驅動中添加一個依賴到另一個spring bean,這個測試上下文將自動被破壞)。只要意識到這一點,並明智地注入豆類。

希望這會有幫助

+0

謝謝,馬克!我在提供上下文的測試類的超類中有一個ContextConfig,但是我發現它缺少定義AppleStorageClient bean的.xml。有了這個說法,根據你的解釋,似乎對我來說重做我目前的「測試」實施更有意義,所以我會放棄它。 –

+0

@Mark Bramnik:只要使用相同的上下文並且不使用DirtiesContext註釋,Spring上下文將只加載一次。也許還有其他限制(https://docs.spring.io/spring/docs/current/spring-framework-reference/html/integration-testing.html) – slowy

相關問題