Problem
Mock一個method已能駕輕就熟了,但如果是一個類別中的欄位呢? 也許你可以替它寫一個get method再去mock就好。但如果今天是一個Constants Intercace,就不行了吧?
public interface Constants { double PI = 3.14159; double PLANCK_CONSTANT = 6.62606896e-34; }
How to solve?
在這我介紹兩種做法,透過Mock Field的方式解決Final修飾宣告的問題。在有宣告Final情況下,不允許使用WhiteBox的方式設置。也許有方法,只是我還沒發現。
WhiteBox
首先看看範例類別,包含一個static與非static的欄位。
public class TestClass { static String field1; String field2; }
要mock只需要透過Whitebox.setInternalState。如果是static欄位,使用TestClass.class;非static欄位就需要傳instance給第一個參數。其餘的就是欄位名稱與內容值。
Whitebox.setInternalState(TestClass.class, "field1", "test1"); TestClass tc = new TestClass(); Whitebox.setInternalState(tc, "field2", "test2"); PowerMock.replayAll(); System.out.println(TestClass.field1); System.out.println(tc.field2);
Mock Field
假如我們用WhiteBox去mock,在Problem中所宣告的Constants,就會收到無法存取final修飾字欄位的例外。
Field field = PowerMock.field(Constants.class, "PI"); field.setAccessible(true); Field modifiersField = Field.class.getDeclaredField("modifiers"); modifiersField.setAccessible(true); modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); field.setDouble(null, 3.3); PowerMock.replayAll(); System.out.println(Constants.PI);
Note. PI需從double改為Double物件。
留言
張貼留言