PowerMock测试 - 设置类的静态字段

时间:2011-03-21 23:59:08

标签: junit static mocking powermock

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

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

其中B是另一个类。

除了setInternalStateFromContext()之外,有没有办法在PowerMock中执行此操作?使用上下文类方法对于设置一个字段似乎有点过分。

感谢。

6 个答案:

答案 0 :(得分:89)

Whitebox.setInternalState(Foo.class, b);

只要您设置非空值,如果只有一个类B的字段,则可以正常工作。如果您不能依赖这种奢侈品,则必须提供字段名称并将null强制转换为您要设置的类型。在这种情况下,你需要写这样的东西:

 Whitebox.setInternalState( Foo.class, "b", (B)null );

答案 1 :(得分:18)

试试这个:

@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));

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

答案 2 :(得分:4)

你只需:

Whitebox.setInternalState(Foo.class, b);

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

答案 3 :(得分: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);
            }       }

答案 4 :(得分:1)

Whitebox.setInternalState(Foo.class, "FIELD_NAME", "value");

答案 5 :(得分:0)

这里我要设置&#34; android.os.Build.VERSION.RELEASE&#34;的值,其中VERSION是类名,RELEASE是最终的静态字符串值。

  

如果基础字段是最终字段,则方法抛出   除非setAccessible(true)成功,否则 IllegalAccessException   此字段和此字段是非静态的,使用 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 的值将返回&#34; Marshmallow &#34;。