一、反射
1.反射的定义
是指程序在运行状态中,可以动态获取对象的信息,动态使用对象的属性和方法。
2.详解
反射的强大之处在于,可以跳过java代码的private权限控制。即可以给private且没有set方法的属性赋值,直接调用private修饰的方法。
二、使用场景
如果想测试一个私有方法,这里有几种解决方案
- 把私有方法权限变为protected或public
- 测试外层的public方法
- 使用反射直接调用私有方法进行测试
首先第一种方案是非常不建议使用的,相当于为了做单元测试修改了原代码,这个方法本来的意义改变了,容易使其他开发同事误解,降低了可读性。
第二种方法,如果逻辑复杂,多个private方法嵌套时,直接调用最外层的public方法就不是一个好的选择,单元测试代码会很混乱,不易维护,一些分支逻辑也不容易被覆盖到,单元测试覆盖率不足。
第三种方法是最可取的,相当于在测试时改变了方法的权限,可以直接在测试类中调用,对源代码又没有任何侵入。
三、一些例子
0.测试类
public class Server {
private Resource resource = new ClassPathResource("webapp");
public Server() {
// ...
}
private boolean isPathExist(String path) {
if (path == null) return false;
if ("".equals(path)) return false;
return true;
}
private void setUrl(WebAppContext webapp) {
try {
webapp.setResourceBase(resource.getURI().toString());
} catch (IOException e) {
// ...
}
}
}
复制代码
1.使用反射调用私有方法
测试私有方法isPathExist
@Test
public void test1() {
Server server = Mockito.mock(Server.class);// mock一个server对象
Method method = Server.class.getDeclaredMethod("isPathExist", String.class);// 通过反射获取要调用的私有方法对象
method.setAccessible(true);// 把私有方法的访问权限设置为true
Boolean bel1 = (Boolean)method.invoke(server, ""); // 调用私有方法
Assert.assertFalse(bel1);
Boolean bel1 = (Boolean)method.invoke(server, "xxx");
Assert.assertTrue(bel1);
}
复制代码
2.使用反射修改私有变量
修改私有变量resource,测试setUrl方法
@Test
public void test2() {
Server server = Mockito.mock(Server.class);// mock一个server对象
Field fieldResource = Server.class.getDeclaredField("resource");// 通过反射获取私有属性对象
fieldResource.setAccessible(true);// 设置访问权限为true
Resource resource = Mockito.mock(ClassPathResource.class);// mock要注入的对象
Mockito.doThrow(new IOException()).when(resource).getURI();// mock要注入对象的行为,调用getURI方法时会抛出IOException
fieldResource.set(server, resource); // 把这个mock的resource注入进server对象中
WebAppContext webapp = new WebAppContext();
// 调用需要测试的方法
Method method = Server.class.getDeclaredMethod("setUrl", WebAppContext.class);
method.setAccessible(true);
method.invoke(server, webapp);
Assert.assertNull(webapp.getResourceBase());
}
复制代码
四、总结
反射配合Mockito使用,可以大大提高单元测试编写效率