Тестирование PowerMock - установить статическое поле класса - PullRequest
41 голосов
/ 22 марта 2011

Мне трудно найти способ установить статическое поле класса. Это в основном так:

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

где B - другой класс.

Есть ли способ сделать это в PowerMock, кроме setInternalStateFromContext()? Использование метода класса контекста кажется немного излишним для установки одного поля.

Спасибо.

Ответы [ 5 ]

91 голосов
/ 18 января 2012
Whitebox.setInternalState(Foo.class, b);

Работает, пока вы устанавливаете ненулевое значение, и , если имеется только одно поле с классом B. Если вы не можете положиться на эту роскошь, вы должны указать имя поля и привести null к типу, который вы хотите установить. В этом случае вам нужно написать что-то вроде этого:

 Whitebox.setInternalState( Foo.class, "b", (B)null );
18 голосов
/ 29 сентября 2013

Попробуйте это:

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

Не работает для примитивов и оболочек примитивов.

4 голосов
/ 22 марта 2011

Вы просто делаете:

Whitebox.setInternalState(Foo.class, b);

где b - это экземпляр B, который вы хотите установить.

1 голос
/ 24 февраля 2018

здесь я собираюсь установить значение для "android.os.Build.VERSION.RELEASE", где VERSION - это имя класса, а RELEASE - окончательное значение статической строки.

Если основное поле является окончательным, метод выдает an IllegalAccessException , если setAccessible (true) не удалось для это поле и это поле нестатические, NoSuchFieldException необходимо добавить при использовании 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");
 }
}

теперь значение String RELEASE вернет " Marshmallow ".

1 голос
/ 02 сентября 2013

Вы можете использовать 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);
            }       }
...