2012-07-09 141 views
0

我在想什麼是測試工廠行爲代碼的最佳實踐。在我的例子中,工廠創建了一些依賴實例,這些實例將被傳遞給FooBar實例的構造函數。測試工廠行爲

public class FooBarFactory { 
    private Dependency1 dependency1; 
    private Dependency2Factory factory; 

    public FooBarFactory(Dependency1 dependency1, Dependency2Factory factory) { 
    this.dependency1 = dependency1; 
    this.factory = factory; 
 } 

    public FooBar create() { 
    return new FooBar(dependency1, factory.create(), new Dependency3()); 
    } 
} 

該依賴關係可以由其他一些工廠創建,或者可以由被測工廠直接創建。

爲了測試工廠行爲,我現在要做的是在FooBar中創建一些受保護的getter以檢索依賴關係,以便我可以斷言構造函數注入並正確創建依賴關係。

這是我不確定的地方。爲了測試的目的添加一些getter讓我有點困擾,因爲它破壞了封裝。我也可以使用反射來檢索字段值,但我通常會考慮這種不好的做法,因爲它很容易中斷。

任何人都可以提供有關此問題的見解?

+0

什麼讓我困惑的是一句'要測試工廠的行爲,我有什麼對現在要做的是創造一些FooBar'保護干將。您不必使用'FooBar'來測試工廠行爲。 – Keppil 2012-07-09 14:15:04

+0

如果我不能使用工廠調用的結果FooBar,我如何測試FooBar已經正確構建? – ebelanger 2012-07-09 14:19:19

+0

你應該通過注入定製的測試依賴項來測試'FooBar',然後在一個單獨的測試測試中測試你的工廠產生的期望。不要混合兩個測試。 – Keppil 2012-07-09 14:21:11

回答

0

作爲一個單元測試,你應該測試你的單元(類),只是這個。

工廠內的工廠創建的值應在其單元測試中進行測試。例如在你的情況下,測試dependency2Factory返回的內容是沒有意義的,因爲爲了FooBar工作,Dependency2Factory也應該工作(如果它不可配置),如果它是可配置的,你可以提供你自己的模擬和這就夠了。

Dependency2Factory應在獨立的單元測試中測試。

您不測試方法List.get(int index)是否每次在您的實施權利中使用列表時都有效?

+0

我明白我需要分離測試問題,在這種情況下,我確實信任Dependency2Factory結果。我想測試的是工廠返回的實例實際上注入到FooBar中,這是工廠的行爲(調用工廠並將實例傳遞給FooBar) – ebelanger 2012-07-09 14:17:50

+0

但在FooBarFactory中,您是否可以配置Dependency2Factory? – 2012-07-09 14:20:14

+0

是的,我會更新代碼。 – ebelanger 2012-07-09 14:21:36

0

我想到的想法是依次注入FooBarFactory的依賴關係,以便它將Dependency1和Dependency2Factory作爲構造函數參數或setter方法中的值。

0

嘲笑怎麼樣?模擬運行測試代碼所需的每個依賴項。 有幾個很好的模擬框架,如mockito。

1

一種解決方案是模擬FooBar類,並驗證構造函數的調用,通過該調用創建了由FooBarFactory#create()返回的實例。使用JMockit嘲諷的API,這樣的測試看起來像:

public class FooBarFactoryTest 
{ 
    @Injectable Dependency1 dep1; 
    @Injectable Dependency2 dep2; 
    @Cascading @Injectable Dependency2Factory dep2Factory; 
    @Mocked FooBar mockFooBar; 
    @Tested factory; 

    @Test 
    public void createFooBarWithProperDependencies() 
    { 
     assertNotNull(factory.create()); 

     new Verifications() {{ new FooBar(dep1, dep2, (Dependency3) withNotNull()); }}; 
    } 
}