Supposons que j'ai une interface avec beaucoup de méthodes que je veux me moquer pour un test, et supposons que je n'ai pas besoin de faire quoi que ce soit, j'ai juste besoin de l'objet sous test pour en avoir une instance. Par exemple, je souhaite exécuter des tests de performances/benchmarks sur un certain code et ne pas souhaiter que les méthodes de cette interface contribuent.façon pas cher de se moquer d'une interface sans surcharge d'exécution
Il y a beaucoup d'outils pour le faire facilement, par exemple
Interface mock = Mockito.mock(Interface.class);
ObjectUnderTest obj = ...
obj.setItem(mock);
ou autre chose.
Cependant, ils viennent tous avec certains frais généraux d'exécution que je préfère éviter:
- Mockito enregistre tous les appels, stashing les arguments pour vérification ultérieure
- JMock et d'autres (je crois) vous obliger à définir ce qu'ils vont faire (pas si grave), et ensuite l'exécution passe par un proxy de différentes sortes pour appeler la méthode.
- Bon vieux java.lang.reflect.Proxy et les amis passent tous au moins quelques appels de méthode sur la pile avant d'arriver à la méthode à invoquer, souvent de manière réfléchie.
(je suis prêt à corriger sur l'un des détails de ces exemples, mais je crois que le principe est.)
Ce que je vise est un non-op « véritable » mise en œuvre de l'interface, comme je pourrais écrire à la main avec tout retournant null
, false
ou 0
. Mais cela n'aide pas si je me sens paresseux et l'interface a beaucoup de méthodes. Alors, comment puis-je générer et instancier une telle implémentation sans opération d'une interface arbitraire à l'exécution?
Il existe des outils tels que Powermock, CGLib qui utilisent la génération de bytecode, mais seulement dans le cadre plus large du moqueur/proxy et je n'ai pas encore trouvé ce qu'il faut choisir parmi les internes. OK, donc l'exemple peut être un peu artificiel et je doute que le proxy ait un impact trop important sur les timings, mais je suis curieux de savoir comment générer une telle classe. Est-ce facile dans CGLib, ASM?
EDIT: Oui, cela est l'optimisation prématurée et il n'y a pas vraiment besoin de le faire. Après avoir écrit cette question, je pense que la dernière phrase ne m'a pas vraiment fait comprendre que je m'intéressais plus à la façon de le faire en principe, et aux moyens faciles de créer une classe dynamique que le cas concret que j'ai donné. Peut-être mal formulé depuis le début.
+1 pour l'édition –
D'accord. Cela sent aussi l'optimisation prématurée, combien de picosecondes sont ces deux couches de pile supplémentaires qui vous coûtent avec les proxies dynamiques de Java, de toute façon? –
Oui, je sais. En toute honnêteté, la partie «comment on peut le faire» est plus importante que «j'ai vraiment besoin de le faire». –