2011-03-21 36 views
34

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

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

其中B是另一类。

有什么办法可以在PowerMock中做到这一点,而不是与setInternalStateFromContext()?使用上下文类方法似乎对设置一个字段有点矫枉过正。

谢谢。

回答

4

你根本:

Whitebox.setInternalState(Foo.class, b); 

其中B是你要设置B的实例。

+0

您想为'b'设置的值是setInternalState()的另一个参数吗? – 2011-03-22 21:05:33

+0

是的,这是第二个参数。例如。 B new = B(); Whitebox.setInternalState(Foo.class,b); – Johan 2011-05-26 09:47:15

+2

只要你设置一个非空值就可以工作。如果只有一个场的b类。 – cproinger 2012-01-18 14:03:20

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

只要你设置一个非空值,如果那里有只与类的B一个领域工作。如果你不能依靠这种奢侈品,你必须提供字段名称并将null转换为你想要设置的类型。在这种情况下,你需要写这样的事:

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

为什么这个答案不被接受? – 2012-06-12 18:30:59

+0

@Matt:因为OP没有注册和“最后看到4月13 '11在16:37”。 – glenneroo 2015-09-10 16:14:49

0

您可以使用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); 
      }  } 
+0

是不是应该是'field.set(YourFieldClass.class,newValue);'? – Arun 2016-06-21 15:53:13

+0

没有。你可以检查api:[link](http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/Field.html#set(java.lang.Object,java.lang.Object ))它说什么_obj - 它的字段应该被修改的对象_ – 2016-06-21 23:10:00

13

试试这个:

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

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

0

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

如果底层字段是最后,该方法抛出一个 IllegalAccessException除非setAccessible(真)已经成功用于 此字段,该字段是非静态,加入NoSuchFieldException需要时您使用field.set()方法

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

没有w字符串值RELEASE将返回“棉花糖”。