54

我很难找到一种方法来设置类的静态字段。基本上是这样的:

public class Foo{
    // ...
    private static B b = null;
}

其中 B 是另一个类。

除了 with 之外,还有什么方法可以在 PowerMock 中做到这一点setInternalStateFromContext()?使用上下文类方法设置一个字段似乎有点矫枉过正。

谢谢。

4

6 回答 6

108
Whitebox.setInternalState(Foo.class, b);

只要您设置了一个非空值,并且只有一个字段的类为B. 如果您不能依赖这种奢侈,则必须提供字段名称并将其null转换为您要设置的类型。在这种情况下,您需要编写如下内容:

 Whitebox.setInternalState( Foo.class, "b", (B)null );
于 2012-01-18T14:09:41.153 回答
21

尝试这个:

@RunWith(PowerMockRunner.class)
@PrepareForTest({Foo.class})
public class FooTest {

    @Test
    public void shouldMockPrivateStaticField() throws IllegalAccessException {
        // given
        Foo foo = new Foo();
        Field field = PowerMockito.field(Foo.class, "b");
        field.set(Foo.class, mock(B.class));

不适用于基元和基元包装器。

于 2013-09-29T19:13:05.803 回答
5

你只需这样做:

Whitebox.setInternalState(Foo.class, b);

其中 b 是您要设置的 B 的实例。

于 2011-03-22T19:24:36.750 回答
2

在这里,我将为“android.os.Build.VERSION.RELEASE”设置值,其中 VERSION 是类名,RELEASE 是最终的静态字符串值。

如果底层字段是final,则该方法抛出IllegalAccessException ,除非该字段的 setAccessible(true)成功并且该字段是非静态的,使用field.set ()方法时需要添加NoSuchFieldException

@RunWith(PowerMockRunner.class)
@PrepareForTest({Build.VERSION.class})
public class RuntimePermissionUtilsTest {
@Test
public void hasStoragePermissions() throws IllegalAccessException, NoSuchFieldException {
    Field field = Build.VERSION.class.getField("RELEASE");
    field.setAccessible(true);
    field.set(null,"Marshmallow");
 }
}

现在 String RELEASE的值将返回“ Marshmallow ”。

于 2018-02-24T13:40:33.417 回答
2
Whitebox.setInternalState(Foo.class, "FIELD_NAME", "value");
于 2020-06-23T15:33:59.453 回答
1

您可以使用getAllStaticFields并尝试设置它们

例子:

YourFieldClass newValue;
final Set<Field> fields = Whitebox.getAllStaticFields(YourClass.class);
        for (final Field field : fields) {
            if (YourFieldClass.class.equals(field.getType())) { // or check by field name
                field.setAccessible(true);
                field.set(YourClass.class, newValue);
            }       }
于 2013-09-02T09:22:07.297 回答