2017
Mar
06
我们要使用 reflect 来测试 Java 的 private method 跟 private variable。
并且用到两个 package: java.lang.reflect.Field 跟 java.lang.reflect.Method。
Private method
下面是一个简单的范例, Class Food 有个 private Method 叫 getLink。
library has private method
- package com.puritys;
- public class Food {
- private String getLink(final int type) {
- switch(type) {
- case 1:
- return "http://xxx.xx.xx/xxx.html";
- case 2:
- return "/xxx.html";
- }
- return "none";
- }
- }
接著我要写一个 Unit test , 为了测试 private method ,我们必需先用 getDeclaredMethod 拿到 Java method ,再修改它的 accessible = true,方式如下:
Test private method
- package com.puritys;
- import static org.junit.Assert.assertEquals;
- import java.lang.reflect.Method;
- import org.junit.*;
- import com.puritys.Food;
- public class FoodTest {
- private Food tester;
- @Before
- public void setUp() throws Exception {
- this.tester = new Food();
- }
- @Test
- public void testApp() throws Exception {
- Method method = this.tester.getClass().getDeclaredMethod("getLink", int.class);
- method.setAccessible(true);
- Object[] parameters = new Object[1];
- parameters[0] = 1;
- String ret = (String) method.invoke(this.tester, parameters);
- assertEquals("The url should be http://", "http://xxx.xx.xx/xxx.html", ret);
- parameters[0] = 2;
- ret = (String) method.invoke(this.tester, parameters);
- assertEquals("The url should be xx", "/xxx.html", ret);
- }
- }
getDeclaredMethod("getLink", int.class)
- 第二个参数是指 getLink 接受的参数型态 ,getLink 有几个参数,这里就要写多少个。
m.setAccessible(true);
- 将 private method 改成 accessible。
Object[] parameters = new Object[1];
parameters[0] = 2;
- 不管 method 需要传几个参数,我们只要宣告一个 Array Object ,set 所有的参数进 Object[]
Private property
下面是一个简单的范例, Class Food 有个 private Property 叫 name 。
private property
- public class Food {
- private String name = "Apple";
- public String getName() {
- return this.name;
- }
- }
测试 private method 的方式跟测 private property 很像,我们先用 getDeclaredField 拿到 Java property ,再用 setAccessible 修改 access 权限。
test private property
- package com.puritys;
- import static org.junit.Assert.assertEquals;
- import java.lang.reflect.Field;
- import org.junit.*;
- import com.puritys.Food;
- public class FoodTest {
- @Test
- public void testGetName() {
- String name = "";
- try {
- Field f = this.tester.getClass().getDeclaredField("name");
- f.setAccessible(true);
- name = (String) f.get(this.tester);
- } catch (Exception e) {
- System.out.println("has exception, error msg = " + e.getMessage());
- }
- assertEquals("The name should be Apple", name, "Apple");
- }
- }