J'utilise Mockito dans certains tests.
J'ai les classes suivantes:
class BaseService {
public void save() {...}
}
public Childservice extends BaseService {
public void save(){
//some code
super.save();
}
}
Je veux me moquer uniquement du deuxième appel ( super.save
) de ChildService
. Le premier appel doit appeler la méthode réelle. Y-a-t-il un moyen de faire ça?
Réponses:
Non, Mockito ne supporte pas cela.
Ce n'est peut-être pas la réponse que vous recherchez, mais ce que vous voyez est le symptôme de la non-application du principe de conception:
Si vous extrayez une stratégie au lieu d'étendre une super classe, le problème est résolu.
Si toutefois vous n'êtes pas autorisé à changer le code, mais que vous devez quand même le tester, et de cette manière maladroite, il y a encore de l'espoir. Avec certains outils AOP (par exemple AspectJ), vous pouvez intégrer du code dans la méthode de la super classe et éviter complètement son exécution (beurk). Cela ne fonctionne pas si vous utilisez des proxys, vous devez utiliser la modification de bytecode (soit le tissage au moment du chargement, soit le tissage au moment de la compilation). Il existe des frameworks moqueurs qui prennent également en charge ce type d'astuce, comme PowerMock et PowerMockito.
Je vous suggère d'opter pour la refactorisation, mais si ce n'est pas une option, vous vous amuserez sérieusement en matière de piratage.
la source
//some codes
code dans une méthode qui pourrait être testée séparément.Si vous n'avez vraiment pas le choix de refactoriser, vous pouvez tout simuler / stub dans l'appel de super méthode, par exemple
la source
BaseService
est abstrait, même si je ne vois pas pourquoi cela serait pertinent.super.validate()
?Envisagez de refactoriser le code de la méthode ChildService.save () vers une méthode différente et testez cette nouvelle méthode au lieu de tester ChildService.save (), de cette façon vous éviterez les appels inutiles à la super méthode.
Exemple:
la source
créez une méthode package protected (suppose une classe de test dans le même package) dans la sous-classe qui appelle la méthode de super classe, puis appelez cette méthode dans votre méthode de sous-classe remplacée. vous pouvez ensuite définir des attentes sur cette méthode dans votre test grâce à l'utilisation du modèle d'espionnage. pas joli mais certainement mieux que de devoir gérer tous les paramètres d'attente pour la super méthode dans votre test
la source
Même si je suis totalement d'accord avec la réponse d'iwein (
), j'admets qu'il y a des moments où l'héritage semble tout simplement naturel, et je ne me sens pas le casser ou le refactoriser juste pour le plaisir d'un test unitaire.
Alors, ma suggestion:
Et puis, dans le test unitaire:
la source
La raison en est que votre classe de base n'est pas publique, alors Mockito ne peut pas l'intercepter en raison de la visibilité, si vous changez la classe de base en public, ou @Override en sous-classe (en tant que public), alors Mockito peut se moquer correctement.
la source
Peut-être que l'option la plus simple si l'héritage a du sens est de créer une nouvelle méthode (package private ??) pour appeler le super (appelons-le superFindall), d'espionner l'instance réelle puis de se moquer de la méthode superFindAll () de la manière dont vous vouliez vous moquer la classe parent un. Ce n'est pas la solution parfaite en termes de couverture et de visibilité, mais elle devrait faire le travail et c'est facile à appliquer.
la source