PowerMock testing - set static field of class

后端 未结 6 1968
孤独总比滥情好
孤独总比滥情好 2020-12-08 00:30

I\'m having difficulty finding a way to set a static field of a class. It\'s basically like this:

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


        
相关标签:
6条回答
  • 2020-12-08 00:39

    Try this:

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

    Don't work for primitives and primitives wrappers.

    0 讨论(0)
  • 2020-12-08 00:43
    Whitebox.setInternalState(Foo.class, b);
    

    Works as long as you set a non-null value, and if theres only one field with the class of B. If you can't rely on that luxury, you have to provide the field-name and cast the null to the type you want to set. In that case you would need to write something like this:

     Whitebox.setInternalState( Foo.class, "b", (B)null );
    
    0 讨论(0)
  • 2020-12-08 00:43
    Whitebox.setInternalState(Foo.class, "FIELD_NAME", "value");
    
    0 讨论(0)
  • 2020-12-08 00:45

    You simply do:

    Whitebox.setInternalState(Foo.class, b);
    

    where b is the instance of B that you want to set.

    0 讨论(0)
  • 2020-12-08 00:46

    You can use getAllStaticFields and try to set them

    Example:

    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 讨论(0)
  • 2020-12-08 00:49

    here I am going to set value for "android.os.Build.VERSION.RELEASE", where VERSION is the class name and RELEASE is the final static string value.

    If the underlying field is final, the method throws an IllegalAccessException unless setAccessible(true) has succeeded for this field and this field is non-static, NoSuchFieldException needs to be added when you use field.set() method

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

    now the value of String RELEASE will return "Marshmallow".

    0 讨论(0)
提交回复
热议问题