2017-07-10 75 views
0

我正在嘗試編寫一些單元測試來聲明適當的密碼套件用於我的應用程序中各種版本的Android SDK。Java中的靜態類的Field.set()

爲了嘲笑的Build.VERSION.SDK_INT我試圖使用Field.set()調用結果...

我有個實用方法,看起來像這樣(從https://stackoverflow.com/a/40303593/1226095拉和鏈接的答案):

private static void mockSdkVersion(Field field, Object newValue) throws Exception { 
    field.setAccessible(true); 
    Field modifiersField = Field.class.getDeclaredField("modifiers"); 
    modifiersField.setAccessible(true); 
    modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); 
    field.set(null, newValue); 
} 

,然後我有利用這種像這樣幾個測試:

@Test 
    public void testApprovedCipherListForApi16() throws Exception { 
     // force SDK_INT to 16 
     mockSdkVersion(Build.VERSION.class.getField("SDK_INT"), 16); 
     // obtain the list of suites that should be returned for API 16 
     ArrayList<String> approvedCipherSuites = ConnectionSpec.APPROVED_CIPHER_SUITES; 
     // assert things... 
    } 

@Test 
public void testApprovedCipherListForApi20() throws Exception { 
    // force SDK_INT to 20 
    mockSdkVersion(Build.VERSION.class.getField("SDK_INT"), 20); 
    // obtain the list of suites that should be returned for API 20 
    ArrayList<String> approvedCipherSuites = ConnectionSpec.APPROVED_CIPHER_SUITES; 
    // assert things... 
} 

這當我運行測試,輸出工作ne,但是當我一次運行它們(比如像詹金斯那樣的CI設置)時,它似乎沒有重置該值(它保持在16),假設它是靜態的。

關於 的任何想法a)我該如何解決這個問題? b)我怎麼可以替代這個呢?

+2

爲什麼「依賴注入」這個詞現在進入我的腦海嗎? –

+0

我知道......但是這個代碼庫相當不可測試......努力解決這個問題...... –

+0

另外,這是一個我正在調用的靜態類,我覺得我會碰到同樣的問題,而不是ab le to Mock(PowerMock目前還不是一個選項) –

回答

0

您需要在每次測試方法調用後重置Build.VERSION。事情是這樣的:

private static final int DEFAULT_VERION = Build.VERSION.SDK_INT; 

@After 
public void after(){ 
    mockSdkVersion(Build.VERSION.class.getField("SDK_INT"), DEFAULT_VERION); 
} 
+0

不是所有的測試後都只運行一次? –

+0

啊不,它在每次測試後都會運行......但不幸的是我沒有看到變化。 –

0

我發現我可以複製我通過簡單地將@Config(sdk = Build.VERSION_CODES.XXX)註解測試方法尋找(假設你正在使用的行爲RoboElectric

http://robolectric.org/configuring/