web-dev-qa-db-fra.com

Pourquoi Mockito ne se moque-t-il pas des méthodes statiques?

J'ai lu quelques discussions ici sur les méthodes statiques et je pense comprendre les problèmes que peuvent entraîner une mauvaise utilisation/une utilisation excessive des méthodes statiques. Mais je n'ai pas vraiment compris pourquoi il est difficile de se moquer des méthodes statiques.

Je connais d'autres frameworks moqueurs, comme PowerMock, qui peuvent le faire, mais pourquoi Mockito ne le peut-il pas?

J'ai lu cet article , mais l'auteur semble être religieusement opposé à la Parole static, c'est peut-être ma mauvaise compréhension.

Une explication facile/lien serait génial.

243
Abidi

Je pense que la raison peut en être que les bibliothèques d'objets mock créent généralement des mocks en créant de manière dynamique des classes lors de l'exécution (à l'aide de cglib ). Cela signifie qu'ils implémentent une interface au moment de l'exécution (c'est ce que EasyMock fait si je ne me trompe pas) ou qu'ils héritent de la classe pour se moquer (c'est ce que Mockito fait si je ne me trompe pas). Les deux approches ne fonctionnent pas pour les membres statiques, car vous ne pouvez pas les remplacer à l'aide de l'héritage.

Le seul moyen de simuler une statique est de modifier le code octet d'une classe à l'exécution, ce qui, je suppose, est un peu plus complexe que l'héritage.

C'est ce que je suppose, pour ce que ça vaut ...

220
Matthias

Si vous devez vous moquer d'une méthode statique, c'est un indicateur fort pour une mauvaise conception. Généralement, vous vous moquez de la dépendance de votre classe sous test. Si votre classe-under-test fait référence à une méthode statique, telle que Java.util.Math # sin par exemple, cela signifie que la classe sous-test a exactement besoin de cette implémentation (précision/vitesse, par exemple). Si vous voulez faire abstraction d'une implémentation concrète de sinus, vous avez probablement besoin d'une interface (vous voyez où cela va)?

28
Jan

Je pense sérieusement que c'est une odeur de code si vous devez également vous moquer des méthodes statiques.

  • Méthodes statiques pour accéder aux fonctionnalités communes? -> Utiliser une instance singleton et l'injecter
  • Code tiers? -> Enveloppez-le dans votre propre interface/délégué (et faites-en un singleton si nécessaire)

La seule fois où cela me semble excessif, ce sont des bibliothèques comme Guava, mais vous ne devriez pas avoir besoin de vous moquer de ce genre de toute façon, car cela fait partie de la logique ... (des choses comme Iterables.transform (..))
Ainsi, votre propre code reste propre, vous pouvez simuler toutes vos dépendances de manière propre et vous disposez d'une couche anti-corruption contre les dépendances externes. J'ai vu PowerMock en pratique et tous les cours pour lesquels nous en avions besoin étaient mal conçus. De plus, l’intégration de PowerMock a parfois posé de graves problèmes
(par exemple https://code.google.com/p/powermock/issues/detail?id=355 )

PS: Même chose pour les méthodes privées. Je ne pense pas que les tests devraient connaître les détails des méthodes privées. Si une classe est si complexe qu'elle tente de se moquer de méthodes privées, c'est probablement un signe pour scinder cette classe ...

6
pete83

Mockito renvoie des objets, mais statique signifie "niveau de classe, pas niveau d'objet". Mockito donnera donc une exception de pointeur null pour static.

4
salsinga

Dans certains cas, les méthodes statiques peuvent être difficiles à tester, en particulier si elles doivent être moquées. C'est pourquoi la plupart des frameworks moqueurs ne les prennent pas en charge. J'ai trouvé que this blog était très utile pour déterminer comment se moquer des méthodes et des classes statiques.

1
Tyler Treat