我试图测试下面的类,它调用一个单例,通过模仿它来初始化私有静态最终变量,如下所示。
这就是我要做的
public class ClassToTest {
private static final boolean CONF_FLAG = Configuration.getConfig()
.get(Status.Initialization).getConfFlag(); // throws an NPE
public methodToTest(TestObject a){
...
}
}
其中状态是一个枚举。
测试等级:
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。班getDeclaredField(“CONF#u FLAG”)
将初始化静态finalClassToTest\CONF#u FLAG
字段,您可以在NullPointerException
中指示结果。
我假设您不能在ClassToTest
中修改源代码。作为修复,您是否可以在setUp()
中执行任何其他操作来初始化配置
单例,例如使用其公共API方法,以便配置。getConfig()。获取(Status.Initialization)。getConfFlag()
调用成功吗?
如果是这样,您可以采用这种方法为测试准备配置
对象,而不是使用反射。
加载类时,将调用此行
private static final boolean CONF_FLAG = Configuration.getConfig().get(Status.Initialization).getConfFlag();
因此,为了解决这个问题,我建议使用PowerMock。
使用PowerMock,您可以轻松跳过不必要的行为,方法是使用@SuppressStatic InitilzationFor
。
此外,您还可以轻松设置内部状态:
Whitebox.setInternalState(ClassToTest.class, "CONF_FLAG", true)
当然,如果你能添加一个新的库,它会起作用。
问题内容: 基于使用Java反射更改私有静态最终字段,我尝试设置私有静态最终字段。 (我知道这非常骇人,但是这个问题与代码质量无关;与Java反射有关。) 此打印 我已经使用OpenJDK 6和7,以及Oracle 7进行了尝试。 我不知道Java反射可以提供什么保证。但是,如果失败了,我以为会有一个(实际上所有反射方法都会抛出异常)。 这是怎么回事 问题答案: Java内联字段可在编译时初始化为
问题内容: 请参考下面的代码。运行代码时,我可以更改最终非静态变量的值。但是,如果我尝试更改最终静态变量的值,则会抛出异常。 我的问题是,为什么在非静态最终变量也不会抛出异常,反之亦然。为什么会有所不同? 问题答案: 该解决方案并非没有缺点,它可能无法在所有情况下都有效: 如果在字段声明中将字段初始化为编译时常量,则对该字段的更改可能不可见,因为该最终字段的使用会在编译时用编译时常量替换。 另一个
问题内容: 我有一堂课,但不幸的是,我需要在运行时更改它。 使用反射我得到这个错误: 有什么办法可以改变价值? 问题答案: 假设没有阻止你执行此操作,则可以使用来绕开并重置修饰符以摆脱,并实际上修改字段。 这是一个例子: 假设没有SecurityException抛出,上面的代码将打印出来”Everything is true”。 实际执行的操作如下: 基本boolean值true和falsein
问题内容: 我有一个带有静态变量的Java类 如何使用反射访问对象? (我有字符串。我需要访问该对象。) 问题答案: 访问静态字段的方式与普通字段完全相同,只是不需要将任何参数传递给方法(可以传递null)。 试试这个:
问题内容: 使用Mockito间谍的用例是什么? 在我看来,每个间谍用例都可以使用callRealMethod进行模拟处理。 我可以看到的一个区别是,如果您希望大多数方法调用都是真实的,则可以节省一些代码行以使用模拟与间谍。是这样还是我错过了更大的前景? 问题答案: 答案在文档中: 真正的部分模拟(自1.8.0开始) 最后,在邮件列表上进行了许多内部辩论和讨论之后,Mockito添加了部分模拟支持
使用Java反射更改私有静态final字段 我按照上面链接中的说明使用java反射更改私有静态final字段。我有一个名为“数据”的对象在“data”内部,有一个名为“type”的私有静态最终变量我想将“type”设置为null。这是我的密码。 我试着在Java1.7上用类似的代码来做这件事,结果成功了。但是在Android上运行此代码会产生以下错误:java。lang.NoSuchFieldEx