Remplacer le programme @PrepareForTest de PowerMock?
J'utilise PowerMock pour simuler des méthodes statiques dans les essais de junit, généralement fait comme suit:
@RunWith(PowerMockRunner.class)
@PrepareForTest({Foo.class,Bar.class})
public class SomeUnitTest {
@Before
public void setUpTest() {
setUpFoo();
setUpBar();
}
private void setUpFoo() {
mockStatic(Foo.class);
when(Foo.someStaticMethod()).thenReturn(1);
}
private void setUpBar() {
mockStatic(Bar.class);
when(Bar.someStaticMethod()).thenReturn(2);
}
@Test
public void someTestCase() {
...
}
}
cela fonctionne très bien, mais je trouve que spécifier le @PrepareForTest
l'annotation m'empêche de rendre mon API de test flexible.
Ce que je voudrais faire est de quelque chose comme ce qui suit:
public class MockLibraryOne {
public static void setUpLibraryOne() {
setUpFoo();
setUpBar();
}
private static void setUpFoo() {
mockStatic(Foo.class);
when(Foo.someStaticMethod()).thenReturn(1);
}
private static void setUpBar() {
mockStatic(Bar.class);
when(Bar.someStaticMethod()).thenReturn(2);
}
}
@RunWith(PowerMockRunner.class)
public class SomeUnitTest {
@Before
public void setUpTest() {
MockLibraryOne.setUpLibraryOne();
}
@Test
public void someTestCase() {
...
}
}
ici, mon test unitaire dépend de LibraryOne
, mais il ne sait pas quelles classes LibraryOne
dépend de, de sorte qu'il ne sait pas quelles classes à ajouter à la @PrepareForTest
annotation.
j'ai pu faire SomeUnitTest
étendre MockLibraryOne
@PrepareForTest
annotation à la MockLibraryOne
classe, mais je vais avoir des dépendances sur plus d' MockLibraryOne
dans d'autres tests unitaires, donc l'héritage n'est pas une solution générale.
Existe-t-il un moyen de préparer programmatiquement une classe à tester sous PowerMock, au lieu d'utiliser le @PrepareForTest
annotation? Par exemple, quelque chose comme ce qui suit:
public class MockLibraryOne {
public static void setUpLibraryOne() {
setUpFoo();
setUpBar();
}
private static void setUpFoo() {
prepareForTest(Foo.class);
mockStatic(Foo.class);
when(Foo.someStaticMethod()).thenReturn(1);
}
private static void setUpBar() {
prepareForTest(Bar.class);
mockStatic(Bar.class);
when(Bar.someStaticMethod()).thenReturn(2);
}
}
je suppose que cela être gentil si PowerMockRunner
traité le @PrepareForTest
annotation un peu différemment: pour chaque classe spécifiée, il ne devrait pas seulement ajouter cette classe (et sa hiérarchie) à la liste des classes pour se préparer à se moquer, mais ensuite examiner cette classe pour voir si elle a un @PrepareForTest
annotations ainsi:
@RunWith(PowerMockRunner.class)
@PrepareForTest({MockLibraryOne.class})
public class SomeUnitTest {
...
}
@PrepareForTest({Foo.class,Bar.class})
public class MockLibraryOne {
...
}
}
Donc dans ce @PrepareForTest
annotation sur SomeUnitTest
trouver MockLibraryOne
et @PrepareForTest
annotation il serait glisser dans Foo.class
et Bar.class
comme bien.
alors peut-être écrire mon propre coureur de test pour remplacer PowerMockRunner
peut être une solution.
Ou peut-être il y a une solution plus simple, à l'aide de PowerMockAgent
classe, par exemple?
edit: Maquette Politiques peuvent être une solution: https://code.google.com/p/powermock/wiki/MockPolicies
edit: Maquette Politiques fonctionne avec PowerMockRunner
mais pas (il me semble)PowerMockRule
(que j'ai parfois besoin en raison de chargeur de classe).
2 réponses
Pourquoi voulez-vous même vous moquer des méthodes statiques? Pourquoi ne pas envelopper ces méthodes statiques dans une classe dont on peut se moquer avec mockito?
class FooWraper {
void someMethod() {
Foo.someStaticMethod()
}
}
et ensuite vous pouvez créer un mock de votre FooWraper. Pas besoin d'utiliser Powermock à tous...