繁体   English   中英

使用Mockito和反射来模拟此私有静态最终变量,我做错了什么?

[英]What am I doing wrong mocking this private static final variable using mockito and reflection?

我正在尝试测试以下类,该类调用一个单例,该单例通过模拟它来初始化私有静态最终变量,方法是遵循示例。

这就是我在做什么

public class ClassToTest {

private static final boolean CONF_FLAG = Configuration.getConfig()
.get(Status.Initialization).getConfFlag(); // throws an NPE

public methodToTest(TestObject a){
...
 }
}

其中Status是一个枚举。

测试类别:

public class TestClassToTest{

 TestObject a; 
 ClassToTest t;
    @Before
public void setUp() throws Exception {
     setFinalStatic(ClassToTest.class.getDeclaredField("CONF_FLAG"), true);// this fails!
    a = mock(TestObject.class);
    t =  new ClassToTest();
}
static void setFinalStatic(Field field, Object newValue) throws Exception {
    field.setAccessible(true);        
    Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
    field.set(null, newValue);
}

}

我不在乎CONF_FLAG的值,但似乎无法嘲笑它。 我究竟做错了什么?

您在TestClassToTest代码看起来不错,但是访问ClassToTest.class.getDeclaredField("CONF_FLAG")将初始化静态的最终ClassToTest#CONF_FLAG字段,您可以在NullPointerException指示结果。

我假设您不能在ClassToTest修改源代码。 作为修复,您可以在setUp()进行任何其他操作以初始化Configuration单例,例如使用其公共API方法,以便对Configuration.getConfig().get(Status.Initialization).getConfFlag()调用成功?

如果是这样,则可以采用这种方法为测试准备Configuration对象,而不是使用反射。

当您的课程被加载时,这行被称为

private static final boolean CONF_FLAG = Configuration.getConfig().get(Status.Initialization).getConfFlag(); 

因此,要解决此问题,我建议使用PowerMock

使用PowerMock可以使用@SuppressStaticInitilizationFor轻松跳过不必要的行为

此外,您将能够轻松设置内部状态:

Whitebox.setInternalState(ClassToTest.class, "CONF_FLAG", true)

当然,如果您可以添加新的库,它将起作用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM