J'ai écrit une usine pour produire des java.sql.Connection
objets:
public class MySQLDatabaseConnectionFactory implements DatabaseConnectionFactory {
@Override public Connection getConnection() {
try {
return DriverManager.getConnection(...);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
Je voudrais valider les paramètres passés DriverManager.getConnection
, mais je ne sais pas comment se moquer d'une méthode statique. J'utilise JUnit 4 et Mockito pour mes cas de test. Existe-t-il un bon moyen de se moquer / de vérifier ce cas d'utilisation spécifique?
java
unit-testing
mocking
mockito
Naftuli Kay
la source
la source
static
méthodes de simulation , mais par accident . Cette limitation (ainsi que l'absence de prise en charge desfinal
classes / méthodes denew
simulation ou des objets -ed) est une conséquence naturelle (mais non intentionnelle) de l'approche utilisée pour implémenter la simulation, où de nouvelles classes sont créées dynamiquement qui implémentent / étendent le type à simuler; d'autres bibliothèques de simulation utilisent d'autres approches qui évitent ces limitations. Cela s'est également produit dans le monde .NET.Réponses:
Utilisez PowerMockito sur Mockito.
Exemple de code:
Plus d'information:
la source
@RunWith(PowerMockRunner.class)
et en dessous@PowerMockRunnerDelegate(JUnit4.class)
.La stratégie typique pour esquiver les méthodes statiques que vous n'avez aucun moyen d'éviter d'utiliser est de créer des objets encapsulés et d'utiliser les objets encapsuleurs à la place.
Les objets wrapper deviennent des façades pour les vraies classes statiques et vous ne les testez pas.
Un objet wrapper pourrait être quelque chose comme
Enfin, votre classe testée peut utiliser cet objet singleton en ayant, par exemple, un constructeur par défaut pour une utilisation réelle:
Et ici, vous avez une classe qui peut facilement être testée, car vous n'utilisez pas directement une classe avec des méthodes statiques.
Si vous utilisez CDI et pouvez utiliser l'annotation @Inject, c'est encore plus facile. Faites simplement votre bean Wrapper @ApplicationScoped, obtenez cette chose injectée en tant que collaborateur (vous n'avez même pas besoin de constructeurs désordonnés pour les tests), et continuez avec la moquerie.
la source
J'ai eu un problème similaire. La réponse acceptée n'a pas fonctionné pour moi, jusqu'à ce que j'effectue le changement :,
@PrepareForTest(TheClassThatContainsStaticMethod.class)
selon la documentation de PowerMock pour mockStatic .Et je n'ai pas besoin de l'utiliser
BDDMockito
.Ma classe:
Ma classe de test:
la source
Comme mentionné précédemment, vous ne pouvez pas vous moquer des méthodes statiques avec mockito.
Si la modification de votre infrastructure de test n'est pas une option, vous pouvez effectuer les opérations suivantes:
Créez une interface pour DriverManager, simulez cette interface, injectez-la via une sorte d'injection de dépendance et vérifiez sur cette maquette.
la source
Observation: lorsque vous appelez une méthode statique au sein d'une entité statique, vous devez modifier la classe dans @PrepareForTest.
Par exemple:
Pour le code ci-dessus, si vous devez simuler la classe MessageDigest, utilisez
Alors si vous avez quelque chose comme ci-dessous:
ensuite, vous devez préparer la classe dans laquelle réside ce code.
Et puis se moquer de la méthode:
la source
Vous pouvez le faire avec un peu de refactoring:
Ensuite, vous pouvez étendre votre classe
MySQLDatabaseConnectionFactory
pour renvoyer une connexion simulée, faire des assertions sur les paramètres, etc.La classe étendue peut résider dans le cas de test, si elle se trouve dans le même package (ce que je vous encourage à faire)
la source
Pour se moquer de la méthode statique, vous devez utiliser un regard Powermock sur: https://github.com/powermock/powermock/wiki/MockStatic . Mockito ne fournit pas cette fonctionnalité.
Vous pouvez lire un bon article sur mockito: http://refcardz.dzone.com/refcardz/mockito
la source
Mockito ne peut pas capturer de méthodes statiques, mais depuis Mockito 2.14.0, vous pouvez le simuler en créant des instances d'appel de méthodes statiques.
Exemple (extrait de leurs tests ):
Leur objectif n'est pas de prendre en charge directement la simulation statique, mais d'améliorer ses API publiques afin que d'autres bibliothèques, comme Powermockito , n'aient pas à s'appuyer sur des API internes ou à dupliquer directement du code Mockito. ( source )
la source
J'ai également écrit une combinaison de Mockito et AspectJ: https://github.com/iirekm/varia/tree/develop/ajmock
Votre exemple devient:
la source
Comme cette méthode est statique, elle a déjà tout ce dont vous avez besoin pour l'utiliser, donc elle va à l'encontre du but de la moquerie. Se moquer des méthodes statiques est considéré comme une mauvaise pratique.
Si vous essayez de le faire, cela signifie qu'il y a un problème avec la façon dont vous souhaitez effectuer les tests.
Bien sûr, vous pouvez utiliser PowerMockito ou tout autre framework capable de le faire, mais essayez de repenser votre approche.
Par exemple: essayez de simuler / fournir les objets, que cette méthode statique consomme à la place.
la source
Utilisez le framework JMockit . Ça a marché pour moi. Il n'est pas nécessaire d'écrire des instructions pour se moquer de la méthode DBConenction.getConnection (). Le code ci-dessous suffit.
@Mock ci-dessous est le package mockit.Mock
la source