web-dev-qa-db-fra.com

Classe finale de simulation avec Mockito 2

Je supprime Powermock du projet sur lequel je travaille actuellement, j'essaie donc de réécrire certains tests unitaires existants uniquement avec Mockito (mockito-core-2.2.28).

Lorsque j'exécute le test, j'ai l'erreur suivante:

org.mockito.exceptions.base.MockitoException:

Impossible de se moquer/d'espionner la classe com.ExternalpackagePath.Externalclass

Mockito ne peut pas se moquer/espionner parce que:

  • classe finale

Je sais que cette question a déjà été posée ( Comment se moquer d'une classe finale avec mockito , Objets simulés appelant des méthodes statiques de classes finales avec Mockito ), mais je n'ai pas trouvé la réponse que je cherche.

Voici un extrait de mon code:

public class MyClassToTest extends TestCase {
    private MyClass myClass;
    @Mock private Externalclass ext;  // This class is final, I would like to mock it

    @Override
    protected void setUp() throws Exception {
        MockitoAnnotations.initMocks(this); // <<<< The exception is thrown here
        ext = Mockito.mock(Externalclass.class);
    }
}

Comme mentionné dans la documentation Mockito ( https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2 , §Mock the unmockable), j'ai ajouté l'org Fichier .mockito.plugins.MockMaker. Voici l'arbre de mon projet:

  • projet
    • src
      • com.packagePath.myPackage
        • ma classe
    • tester
      • com.packagePath.myPackage
        • myClassToTest
      • ressources
        • mockito-extensions
          • org.mockito.plugins.MockMaker

J'essaie également de mettre le répertoire "resources" dans "src", dans un sous-répertoire appelé "test", mais le résultat est toujours le même.

Je pensais que se moquer d'une finale était possible avec Mockito v2. Quelqu'un at-il une idée de ce qui manque ici?

Merci!

13
Ptiseb

Eh bien, j'ai trouvé ce qui ne va pas ici, cela peut être utile pour d'autres personnes. Mon arborescence de projet est erronée, j'ai mis l'org.mockito.plugins.MockMaker dans un répertoire "mockito-extension" directement dans "src". Voici mon arbre maintenant:

  • projet
    • src
      • com.packagePath.myPackage
        • ma classe
      • mockito-extensions
        • org.mockito.plugins.MockMaker
  • tester
    • com.packagePath.myPackage
      • myClassToTest
8
Ptiseb

Bizarre que votre solution semble fonctionner.
Selon leur documentation sur Github c'est écrit.

La moquerie des classes et des méthodes finales est une fonction d'incubation opt-in. Il utilise une combinaison de Java instrumentation d'agent et sous-classement afin d'activer la mockability de ces types. Comme cela fonctionne différemment de notre mécanisme actuel et que celui-ci a des limites différentes et que nous voulons rassembler de l'expérience et les commentaires des utilisateurs, cette fonctionnalité devait être explicitement activée pour être disponible; cela peut être fait via le mécanisme d'extension mockito en créant le fichier src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker contenant une seule ligne:

mock-maker-inline

Après avoir créé ce fichier, Mockito utilisera automatiquement ce nouveau moteur et on peut faire:

 final class FinalClass {
   final String finalMethod() { return "something"; }
 }

 FinalClass concrete = new FinalClass(); 

 FinalClass mock = mock(FinalClass.class);
 given(mock.finalMethod()).willReturn("not anymore");

 assertThat(mock.finalMethod()).isNotEqualTo(concrete.finalMethod());

Dans les étapes suivantes, l'équipe apportera une manière programmatique d'utiliser cette fonctionnalité. Nous identifierons et fournirons un support pour tous les scénarios non modifiables. Restez à l'écoute et faites-nous savoir ce que vous pensez de cette fonctionnalité!

Ma structure de travail ressemble maintenant à ceci.

enter image description here

30
tim

Je ne pouvais pas non plus le faire fonctionner avec le fichier de configuration; cependant, l'équipe Mockito est très gentille et fournit également un artefact Mockito préconfiguré qui ne nécessite aucune configuration dans le projet cible.

Donc, si vous utilisez Gradle et souhaitez tester votre code Kotlin, ajoutez simplement ceci aux dépendances de votre projet:

testCompile 'org.mockito:mockito-inline:2.8.9'
testCompile('com.nhaarman:mockito-kotlin:1.5.0') {
    exclude group: 'org.jetbrains.kotlin'
    exclude group: 'org.mockito'
}
16
Thomas Keller

Vous semblez avoir eu un problème de chemin de classe, tout comme moi.

Votre configuration précédente aurait également fonctionné, mais il semble que

project/test/resources

n'était pas dans votre chemin de classe.

J'ai eu le même problème lorsque j'ai essayé de l'exécuter avec IntelliJ. J'ai simplement marqué le répertoire des ressources comme racine de ressources de test et cela a bien fonctionné. Louez les dieux de Mockito!

3
Somaiah Kumbera

Cette solution a fonctionné pour moi: au lieu de

testCompile "org.mockito:mockito-Android:2.9.0"

dans le fichier gradle, remplacez-le par

testCompile group: 'org.mockito', name: 'mockito-inline', version: '2.9.0' 

et ça marcherait.

0
S.Javed