web-dev-qa-db-fra.com

PowerMock testing - définit le champ statique de la classe

J'ai du mal à trouver un moyen de définir un champ statique d'une classe. C'est fondamentalement comme ça:

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

où B est une autre classe.

Existe-t-il un moyen de faire cela dans PowerMock autrement qu'avec setInternalStateFromContext()? L'utilisation de la méthode de la classe de contexte semble un peu exagérée pour la définition d'un champ.

Merci.

38
Craig Anderson
Whitebox.setInternalState(Foo.class, b);

Fonctionne tant que vous définissez une valeur non NULL, et s'il n'y a qu'un seul champ avec la classe B. Si vous ne pouvez pas compter sur ce luxe, vous devez fournir le nom du champ et transtyper la variable null au type que vous souhaitez définir. Dans ce cas, vous devez écrire quelque chose comme ceci:

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

Essaye ça:

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

Ne travaillez pas pour les primitives et les wrappers de primitives.

17
Marcin Stachniuk

Vous faites simplement:

Whitebox.setInternalState(Foo.class, b);

où b est l'instance de B que vous souhaitez définir.

4
Johan

Vous pouvez utiliser getAllStaticFields et essayer de les définir

Exemple:

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);
            }       }
1
Tomasz Przybylski

ici, je vais définir la valeur de "Android.os.Build.VERSION.RELEASE", où VERSION est le nom de la classe et RELEASE est la valeur de la chaîne statique finale. 

Si le champ sous-jacent est final, la méthode jette un IllegalAccessException sauf si setAccessible (true) a réussi pour ce champ et ce champ est non statique, NoSuchFieldException doit être ajouté lorsque vous utilisez 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");
 }
}

maintenant la valeur de String RELEASE retournera "Marshmallow".

0
anand krish