使用反射修改工具类里的final static 字段
单元测试遇到如下的代码块,因为jdk的值是从System.getProperty("java.version")
里获取的,所以一直是1.8版本jdk
public class FieldHelper {
private static final IFieldHelper fieldHelperInterface;
static {
String version = System.getProperty("java.version");
if (version.contains("1.8.")) {
fieldHelperInterface = new Jdk8FieldHelper();
} else {
fieldHelperInterface = new Jdk6or7FieldHelper();
}
}
}
这个时候使用反射把fieldHelperInterface
字段修改掉即可
Field field = FieldHelper.class.getDeclaredField("fieldHelperInterface")
field.setAccessible(true)
Field modifiersField = Field.class.getDeclaredField("modifiers")
modifiersField.setAccessible(true)
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL)
FieldHelper.IFieldHelper fieldHelperInterface = new FieldHelper.Jdk6or7FieldHelper()
field.set(null, fieldHelperInterface)
PowerMock mock static method
测试私有方法
使用powermock
的Whitebox.invokeMethod()
方法可以调用对象的私有方法
//第一个参数为对象,第二个参数为该对象的私有方法名,后面的可变参数为传入的参数
Whitebox.invokeMethod(demoRegisterService, "sendRegisterEvent", organizationDO, userDO, userDO, userDO)
如何mock在方法内创建的对象
有如下类,在method()
方法里,创建了一个Animal对象,返回name
public class User {
public String method (){
Animal animal = new Animal("dog");
return animal.getName();
}
}
public class Animal {
private String name;
public Animal(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
由于方法体内使用硬编码dog
创建的用户,所以返回值是dog,如果我们想改变animal.getName()
的返回值,可以使用PowerMockito.whenNew
指定方法内新建对象的返回值。
//这里指定的类是
@PrepareForTest(User.class)
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(Sputnik.class)
class GatewayHelperSpec extends Specification {
def "test"() {
given:
def animal = Mock(Animal)
PowerMockito.whenNew(Animal.class).withAnyArguments().thenReturn(animal)
animal.getName() >> "cat"
User user = new User()
when:
def result = user.getName()
then:
result=="cat"
}
}