web-dev-qa-db-fra.com

Comment se moquer de la méthode statique sans powermock

Existe-t-il un moyen de se moquer de la méthode statique statique lors des tests dans JUnit?

Je sais que Powermock peut se moquer des appels statiques, mais je ne souhaite pas utiliser Powermock.

Y a-t-il des alternatives?

18
gati sahu

(Je suppose que vous pouvez utiliser Mockito cependant) Rien de particulier ne me vient à l’esprit, mais j’ai tendance à utiliser la stratégie suivante quand il s’agit de situations comme celle-ci:

1) Dans la classe sous test, remplacez l'appel direct statique par un appel à une méthode au niveau du package qui englobe l'appel statique lui-même:

public class ToBeTested{

    public void myMethodToTest(){
         ...
         String s = makeStaticWrappedCall();
         ...
    }

    String makeStaticWrappedCall(){
        return Util.staticMethodCall();
    }
}

2) Espionnez la classe sous test pendant le test et simulez la méthode au niveau du paquet enveloppé:

public class ToBeTestedTest{

    @Spy
    ToBeTested tbTestedSpy = new ToBeTested();

    @Before
    public void init(){
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void myMethodToTestTest() throws Exception{
       // Arrange
       doReturn("Expected String").when(tbTestedSpy).makeStaticWrappedCall();

       // Act
       tbTestedSpy.myMethodToTest();
    }
}
12
Maciej Kowalski

Lorsque vous avez un code statique qui vous cause des problèmes lors de vos tests unitaires; de sorte que vous sentiez que vous deviez "vous moquer", vous avez exactement ces options:

  • Vous vous tournez vers PowerMock (ito). Fonctionne bien.
  • Vous vous tournez vers JMockit. Fonctionne bien aussi.
  • Si vous testez du code que vous avez écrit vous-même , vous voudrez peut-être revenir en arrière et vous demander: "pourquoi ai-je écrit du code que je trouve difficile à Test de l'unité?"

En d'autres termes: si vous souhaitez utiliser un framework moqueur, vous devez utiliser l'un de ceux répertoriés ci-dessus. D'un côté, c'est absolument juste. statique fait partie du Java; pourquoi ne pas utiliser un cadre qui vous permette de le gérer?

Mais bien sûr: vous avez toujours l'appel statique dans votre code de production. Conduisant à un couplage étroit et empêchant le polymorphisme .

Donc: si vous pouvez vous débarrasser de l’appel statique (même si vous n’utilisez que la solution de contournement suggérée dans l’autre réponse), tant mieux. Si non: Mockito ne peut pas aider; vous avez besoin de la magie de la manipulation du code byte resp. Agents JVM.

4
GhostCat

J'ai eu beaucoup de chance avec quelque chose de similaire à ce que Maciej a suggéré dans sa réponse ci-dessus. En Java8, j'aime bien intégrer ces méthodes statiques à des interfaces fonctionnelles pour les rendre plus simples à injecter ou à simuler. Par exemple:

public class MyClass {
    private MyStaticWrapper staticWrapper;

    public MyClass(final MyStaticWrapper staticWrapper) {
        this.staticWrapper = staticWrapper;
    }

    public void main() {
        ...
        staticWrapper.doSomething();
        ...    
    }
}    

public interface MyStaticWrapper {
    default void doSomething() {
      Util.annoyingUntestableStaticFunction();
    }
}
0
Bryce