由于 Java 私有方法不允许在类的外部进行访问,当我们在写 junit 测试的时候,就无法像测试其他方法一样通过对象调用的方式对 private 方法进行单独测试,下面分享测试私有方法的两种方式
待测类代码
public class Calculator {
private int add(int a, int b) {
return a + b;
}
}
使用反射机制
Java 反射能在运行时获得类的属性和方法,故可以通过 Java 的反射机制对私有方法进行测试,代码如下
@Test
public void reflectTest() throws Exception {
Class<?> clazz = Class.forName(Calculator.class.getName());
Calculator calculator = (Calculator) clazz.newInstance();
Method addMethod = clazz.getDeclaredMethod("add", int.class, int.class);
addMethod.setAccessible(true);
int result = (int) addMethod.invoke(calculator, 1, 2);
assertThat(result, is(equalTo(3)));
}
使用 PowerMock 测试私有方法
Java 单元测试中比较流行的 Mock 测试框架有jMock
、EasyMock
、Mockito
等,但是这些 Mock 工具都不能 Mock static、final、private 方法等,而PowerMock
能够做到,而且还支持对私有方法进行测试
使用前需要先引入PowerMock
依赖
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.4</version>
<scope>test</scope>
</dependency>
调用方法代码示例
public class CalculatorTest {
private Calculator calculator;
@Before
public void setUp() {
calculator = new Calculator();
}
@Test
public void add() throws Exception {
int result = Whitebox.invokeMethod(calculator, "add", 1, 2);
assertThat(result, is(equalTo(3)));
}
}
Whitebox.invokeMethod()
前两个参数分别为需要调用的类的实例、静态方法的名称,后面的不定长参数为调用目标方法的参数。可见,使用PowerMock
测试静态方法相比于反射的方式,代码更加简洁,可读性也更好