2016-08-25 35 views
1

下檢驗,假設我的系統是這樣的:如何禁用靜態初始化程序?

public class SysUnderTest { 
    public int foo() { 
     Trouble trouble1 = new Trouble(); 
     Trouble trouble2 = new Trouble(); 
     return trouble1.water(1) + trouble2.water(2); 
    } 
} 

測試將看起來像

public class DummyTest { 

    @Tested SysUnderTest sut; 
    @Mocked Trouble trouble; 

    @Test 
    public void testTrouble() { 
     new Expectations() {{ 
      trouble.water(anyInt); returns(10, 20); 
     }}; 

     assertThat("mocked result", sut.foo(), is(30)); 

     new FullVerificationsInOrder() {{ 
      Trouble t1 = new Trouble(); 
      Trouble t2 = new Trouble(); 
      t1.water(1); 
      t2.water(2); 
     }}; 
    } 
} 

然而,Trouble實際上是一個第三方的lib類,我無法控制,它靜態初始化會在測試環境中失敗。

public class Trouble { 
    static { 
     troubleInitialize(); 
    }; 

    public int water(int i) { 
     return 0; 
    } 

    private static void troubleInitialize() { 
     throw new RuntimeException("Trouble"); 
    } 
} 

我知道我可以使用MockUp<Trouble>擺脫靜態初始化的,但我不知道怎麼做的情況下,使用它,因爲我想(在我的現實情況下),能夠區分兩個新實例(在SysUnderTest中創建)並驗證其調用。我曾嘗試不同的方法,但都失敗了一些原因

  1. @Before/@BeforeClass添加new MockUp<Trouble>(){@Mock void $clinit(){} };,並保持@Mocked Trouble trouble;。它似乎不工作,因爲實體模型動作發生在DummyTest類被加載後,將加載(未修改)Trouble類將靜態初始化

  2. TestSuite添加新的樣機期間拋出異常,並撥打套件DummyTest,類似的問題爲1.

  3. 簡單地說,將20, 30返回假類的行爲,並刪除Expectations/Verifications的使用情況,但我無法驗證哪個實例用什麼參數調用。

有沒有更好的方法來解決我的問題?其實我想繼續使用Expectaitons/Verifications,我想要的是在單元測試期間禁用靜態初始化器的一些方法。

回答

2

使用stubOutClassInitialization在使用Mocked時將模擬類的靜態init更改爲空方法。

@Mocked(stubOutClassInitialization=true) Trouble trouble; 
+0

無法想象我錯過了這個功能!它完全符合我的期望! –

+0

很高興能有一個簡單的答案。 :) – pmcevoy12