Comment simuler une méthode privée pour tester avec PowerMock?

J’ai un cours que je voudrais tester avec une méthode publique qui appelle privé. Je voudrais supposer que la méthode privée fonctionne correctement. Par exemple, j’aimerais quelque chose comme doReturn....when... J’ai trouvé qu’il y avait une solution possible avec PowerMock , mais cette solution ne fonctionne pas pour moi. Comment ça peut être fait? Quelqu’un at-il eu ce problème?

Je ne vois pas de problème ici. Avec le code suivant utilisant l’API Mockito, j’ai réussi à faire exactement cela:

 public class CodeWithPrivateMethod { public void meaningfulPublicApi() { if (doTheGamble("Whatever", 1 << 3)) { throw new RuntimeException("boom"); } } private boolean doTheGamble(String whatever, int binary) { Random random = new Random(System.nanoTime()); boolean gamble = random.nextBoolean(); return gamble; } } 

Et voici le test JUnit:

 import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anySsortingng; import static org.powermock.api.mockito.PowerMockito.when; import static org.powermock.api.support.membermodification.MemberMatcher.method; @RunWith(PowerMockRunner.class) @PrepareForTest(CodeWithPrivateMethod.class) public class CodeWithPrivateMethodTest { @Test(expected = RuntimeException.class) public void when_gambling_is_true_then_always_explode() throws Exception { CodeWithPrivateMethod spy = PowerMockito.spy(new CodeWithPrivateMethod()); when(spy, method(CodeWithPrivateMethod.class, "doTheGamble", Ssortingng.class, int.class)) .withArguments(anySsortingng(), anyInt()) .thenReturn(true); spy.meaningfulPublicApi(); } } 

Une solution générique qui fonctionnera avec tout framework de test ( si votre classe n’est pas final ) consiste à créer manuellement votre propre maquette.

  1. Changez votre méthode privée en protégée.
  2. Dans votre classe de test, étendez la classe
  3. remplacer la méthode précédemment privée pour retourner la constante que vous voulez

Cela n’utilise aucun framework, ce n’est pas aussi élégant, mais cela fonctionnera toujours: même sans PowerMock. Vous pouvez également utiliser Mockito pour effectuer les étapes 2 et 3 si vous avez déjà effectué l’étape 1.

Pour simuler directement une méthode privée, vous devez utiliser PowerMock comme indiqué dans l’ autre réponse .

je sais un moyen que vous pouvez appeler vous fonction privée pour tester dans mockito

 @Test public void commandEndHandlerTest() throws Exception { Method retryClientDetail_privateMethod =yourclass.class.getDeclaredMethod("Your_function_name",null); retryClientDetail_privateMethod.setAccessible(true); retryClientDetail_privateMethod.invoke(yourclass.class, null); } 

Pour une raison quelconque, la réponse de Brice ne fonctionne pas pour moi. J’ai pu le manipuler un peu pour le faire fonctionner. C’est peut-être parce que j’ai une nouvelle version de PowerMock. J’utilise 1.6.5.

 import java.util.Random; public class CodeWithPrivateMethod { public void meaningfulPublicApi() { if (doTheGamble("Whatever", 1 << 3)) { throw new RuntimeException("boom"); } } private boolean doTheGamble(String whatever, int binary) { Random random = new Random(System.nanoTime()); boolean gamble = random.nextBoolean(); return gamble; } } 

La classe de test se présente comme suit:

 import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anySsortingng; import static org.powermock.api.mockito.PowerMockito.doReturn; @RunWith(PowerMockRunner.class) @PrepareForTest(CodeWithPrivateMethod.class) public class CodeWithPrivateMethodTest { private CodeWithPrivateMethod classToTest; @Test(expected = RuntimeException.class) public void when_gambling_is_true_then_always_explode() throws Exception { classToTest = PowerMockito.spy(classToTest); doReturn(true).when(classToTest, "doTheGamble", anySsortingng(), anyInt()); classToTest.meaningfulPublicApi(); } }