Mock Class Filed

Mock一個method已能駕輕就熟了,但如果是一個類別中的欄位呢? 也許你可以替它寫一個get method再去mock就好。但如果今天是一個Constants Intercace,就不行了吧?

public interface Constants {
	double PI = 3.14159;
	double PLANCK_CONSTANT = 6.62606896e-34;
}

在這我介紹兩種做法,透過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物件。