J'ai un code un peu comme ceci ci-dessous:
Class A {
public boolean myMethod(someargs) {
MyQueryClass query = new MyQueryClass();
Long id = query.getNextId();
// some more code
}
}
Class MyQueryClass {
....
public Long getNextId() {
//lot of DB code, execute some DB query
return id;
}
}
Maintenant, je suis en train d'écrire un test pour A.myMethod(someargs)
. Je souhaite ignorer la méthode réelle query.getNextId()
et renvoyer à la place une valeur de stub. En gros, je veux me moquer de MyQueryClass
.
Donc, dans mon cas de test, j'ai utilisé:
MyQueryClass query = PowerMockito.mock(MyQueryClass.class);
PowerMockito.whenNew(MyQueryClass.class).withNoArguments().thenReturn(query);
when(query.getNextId()).thenReturn(1000000L);
boolean b = A.getInstance().myMethod(args);
//asserts
J'ai utilisé @RunWith(PowerMockRunner.class)
et @PrepareForTest({MyQueryClass.class})
au début de ma classe de test.
Mais lorsque je débogue le test, il appelle toujours la méthode réelle getNextId()
de la classe MyQueryClass
.
Qu'est-ce que j'oublie ici? Est-ce que n'importe qui peut aider comme je suis nouveau à Mockito et à PowerMockito.
Vous devez mettre la classe où le constructeur est appelé dans l'annotation @PrepareForTest
au lieu de la classe en cours de construction - voir Construction fictive de nouveaux objets .
Dans ton cas:
✗ @PrepareForTest(MyQueryClass.class)
✓ @PrepareForTest(A.class)
Plus général:
✗ @PrepareForTest(NewInstanceClass.class)
✓ @PrepareForTest(ClassThatCreatesTheNewInstance.class)
Comme @TrueDub mentionné dans sa réponse acceptée, vous devez ajouter la classe où le constructeur est appelé au @PrepareForTest
.
Cependant, si vous faites cela, la couverture pour cette classe, telle que rapportée par eclemma et Sonar, sera nulle pour cette classe.
Nous allons remplacer Javassist par ByteBuddy (# 727) et il devrait aider à résoudre ce vieux problème. Mais pour le moment, il n’ya AUCUN MOYEN D’UTILISER PowerMock avec JaCoCo Une instrumentation à la volée. Et aucune solution de contournement à obtenir une couverture de code dans l'IDE.
La solution ici serait donc de refactoriser le code afin d’utiliser une fabrique statique qui renverrait une instance de cette classe puis la simulait de manière statique.