Getting Started
use : rely on EasyMock or Mockito and a test framework
Bypass Encapsulation mock 绕过封装
翻译自
https://github.com/powermock/powermock/wiki/Bypass-Encapsulation
Quick summary
class provides a set of methods which could you help bypass encapsulation if it required. Usually, it's not a good idea to get/modify non-public fields, but sometimes it's only way to cover code by test for future refactoring.
- Use
Whitebox.setInternalState(..)
to set a non-public member of an instance or class. 设置内部私有成员 - Use
Whitebox.getInternalState(..)
to get a non-public member of an instance or class. 获取内部私有成员 - Use
Whitebox.invokeMethod(..)
to invoke a non-public method of an instance or class. 调用私有方法 - Use
Whitebox.invokeConstructor(..)
to create an instance of a class with a private constructor. 调用私有构造函数
举例
- 1 调用私有方法
private int sum(int a, int b) {
return a+b;
}
int sum = Whitebox.<Integer> invokeMethod(myInstance, "sum", 1, 2);
- 2 私有方法重载情况
...
private int myMethod(int id) {
return 2*id;
}
private int myMethod(Integer id) {
return 3*id;
}
...
根据传入参数class判断用哪个
int result = Whitebox.<Integer> invokeMethod(myInstance, new Class<?>[]{int.class}, "myMethod", 1);
- 3 调用私有构造器
public class PrivateConstructorInstantiationDemo {
private final int state;
private PrivateConstructorInstantiationDemo(int state) {
this.state = state;
}
public int getState() {
return state;
}
}
调用:
PrivateConstructorInstantiationDemo instance = WhiteBox.invokeConstructor(
PrivateConstructorInstantiationDemo.class, 43);
- 构造器重载的情况
public class PrivateConstructorInstantiationDemo {
private final int state;
private PrivateConstructorInstantiationDemo(int state) {
this.state = state;
}
private PrivateConstructorInstantiationDemo(Integer state) {
this.state = state;
// do something else
}
public int getState() {
return state;
}
}
调用:
PrivateConstructorInstantiationDemo instance = Whitebox.invokeConstructor(PrivateConstructorInstantiationDemo.class, new Class<?>[]{Integer.class}, 43);