使用 getter 时最终字段的 PowerMock setInternalState 不起作用

PowerMock setInternalState for final field not working when using a getter

我有一个class这样的。

public class ExampleClass {
    private final String finalString = "final";

    public String getFinalString() {
        return finalString;
    }
}

这是我的样本测试 class,它试图改变 finalString

的值
public class ExampleClassTest {
    private ExampleClass exampleClass = new ExampleClass();

    @Before
    public void setUp() throws Exception {
        Whitebox.setInternalState(exampleClass,"finalString","mocked");
    }

    @Test
    public void name() throws Exception {
        assertEquals("mocked", exampleClass.getFinalString()); //failing 
    }
}

但是在这里,我的断言失败了。 exampleClass.getFinalString() 的值声称是 "final".

但是当我在断言行调试代码并检查字段 finalString 的值或者当我尝试使用反射(下面的代码)获取字段 finalString 的值时,它显示 "mocked" 值。

我的反射码

Field finalStringField = exampleClass.getClass().getDeclaredField("finalString");
finalStringField.setAccessible(true);
assertEquals("mocked",finalStringField.get(exampleClass)); //passing

有人知道这里的技巧吗?

PS:我在决赛场的getter确实看起来很奇怪。请忽略它。

而且,即使我添加

@RunWith(PowerMockRunner.class)
@PrepareForTest(ExampleClass.class)

在我的测试顶部 class,相同的结果

确保您使用的是哪个 Whitebox,您应该使用 PowerMock 只需将 Whitebox 行更新为

PowerMock.Whitebox.setInternalState(exampleClass, "finalString", "mocked");

,如果上述方法不起作用,请尝试模拟对象并调用真实方法:

@RunWith(PowerMockRunner.class)
@PrepareForTest(ExampleClass.class)
public class ExampleClassTest {

    private ExampleClass exampleClass;

    @Before
    public void setUp() throws Exception {
        exampleClass = PowerMock.mock(ExampleClass.class, Mocktio.CALL_REAL_METHOD);
        PowerMock.Whitebox.setInternalState(exampleClass, "finalString", "mocked");
    }

    @Test
    public void name() throws Exception {
        assertEquals("mocked", exampleClass.getFinalString());
    }
}

我自己找到了答案。获取要断言的值的正确方法如下。为此,我们需要使用 Whitebox.getInternalStateWhitebox.getField 方法之一

所以会是以下之一

assertEquals("mocked", Whitebox.getInternalState(exampleClass,"finalString"));

assertEquals("mocked",Whitebox.getField(exampleClass.getClass(),"finalString").get(exampleClass));