Méthode finale moqueur
J'ai besoin de se moquer un peu de classe avec la méthode définitive à l'aide de mockito. J'ai écrit quelque chose comme cela
@Test
public void test() {
B b = mock(B.class);
doReturn("bar called").when(b).bar();
assertEquals("must be \"overrided\"", "bar called", b.bar());
//bla-bla
}
class B {
public final String bar() {
return "fail";
}
}
Mais il échoue.
J'ai essayé quelques "hack" et ça fonctionne.
@Test
public void hackTest() {
class NewB extends B {
public String barForTest() {
return bar();
}
}
NewB b = mock(NewB.class);
doReturn("bar called").when(b).barForTest();
assertEquals("must be \"overrided\"", "bar called", b.barForTest());
}
Cela fonctionne, mais les "odeurs".
Alors, Où est la bonne façon?
Grâce.
- L'idéal est de ne pas avoir besoin de se moquer de finale méthodes, bien sûr. Vous n'avez pas nous dit rien au sujet de pourquoi vous essayez de faire cela. J'ai l'habitude de tenter dur de garder mon dépendances à des interfaces... est-il possible que vous pouvez utiliser une interface de procurations de la vraie classe (en supposant que vous ne pouvez pas modifier la classe elle-même)?
- Cette classe à partir d'un code existant.
- Vous n'avez pas l'option à modifier? Ou proxy via une autre classe qui implémente une interface?
- Skeet: je ne peux pas le modifier. Vous voyez, c'est la bibliothèque (SWT). Il y a l'interface IFigure et la mise en œuvre - la Figure. Mais IFigure ne débite pas contient getLocation().
- Skeet: désolé, pas de SWT. C'est org.eclipse.draw2d.
Vous devez vous connecter pour publier un commentaire.
Il n'y a pas de support pour se moquant de finale méthodes de Mockito.
Comme Jon Skeet a commenté vous devriez être à la recherche d'un moyen d'éviter la dépendance à l'égard de la méthode finale. Cela dit, il y a des voies de sortie, par le biais de la manipulation de bytecode (par exemple, avec PowerMock)
Un comparaison entre Mockito et PowerMock va expliquer les choses en détail.
De la Mockito FAQ:
Vous pouvez utiliser Powermock avec Mockito, alors vous n'avez pas besoin de sous-classe B.class. Il suffit d'ajouter ce à le haut de votre classe de test
@PrepareForTest
charge Powermock à l'instrument B.class pour faire la finale et méthodes statiques mockable. Un inconvénient de cette approche est que vous devez utiliser PowerMockRunner qui s'oppose à l'utilisation d'autres les coureurs de l'épreuve, comme au Printemps de test runner.NullPointerException
de la même manière lorsque vous n'utilisez pas le@RunWith
et@PrepareForTest
. Semble que la classe n'a pas été intrumented pour une raison quelconque.PowerMockito.mock
, pasMockito.mock
.Mockito 2 prend désormais en charge se moquant de finale de méthodes mais c'est une "incubation" caractéristique. Il nécessite quelques étapes à suivre pour l'activer, qui sont décrits ici:
https://github.com/mockito/mockito/wiki/What's-new-in-Mockito-2#mock-the-unmockable-opt-in-mocking-of-final-classesmethods
verify
ingfinal
méthodes? Évidemment, j'ai eu un coup d'oeil à cette page, mais il n'a pas l'air de dire quoi que ce soit...Mockito 2.x prend désormais en charge méthode finale et de la finale de la classe stubbing.
À partir de la documentation:
En supposant que la classe B est comme ci-dessous:
Il y a une meilleure façon de le faire sans l'aide de PowerMockito cadre.
Vous pouvez créer un ESPION pour votre classe et peut se moquer de votre méthode finale.
Ci-dessous est la façon de le faire:
Je viens de faire la même chose. Mon cas est que je voulais m'assurer que la méthode n'a pas "Provoquer" une erreur mais comme c'est un catch/log/retour de la méthode, je ne pouvais pas tester directement, sans modification de la classe.
Je voulais simplement se moquer de l'enregistreur j'ai passé, mais quelque chose au sujet de se moquer de la "Journal" de l'interface n'a pas l'air de fonctionner et se moquant d'une classe comme "SimpleLog" n'a pas fonctionné parce que ces méthodes sont finales.
J'ai fini par la création d'un anonyme intérieure classe étendant SimpleLog que overrid le niveau de base "du journal(niveau, une chaîne, une erreur de méthode que les autres, tous les délégué à, puis juste en attente d'un appel avec un "niveau" de 5.
En général, l'extension d'une classe de comportement n'est pas vraiment une mauvaise idée, peut-être préférable de se moquant de toute façon si c'est pas trop compliqué.