J'ai une classe que je voudrais tester avec une méthode publique qui appelle une méthode privée. J'aimerais supposer que la méthode privée fonctionne correctement. Par exemple, je voudrais quelque chose comme doReturn....when...
. J'ai trouvé qu'il y a solution possible avec PowerMock , mais cette solution ne fonctionne pas pour moi. Comment cela peut-il ê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 à le faire:
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.anyString;
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", String.class, int.class))
.withArguments(anyString(), anyInt())
.thenReturn(true);
spy.meaningfulPublicApi();
}
}
Une solution générique qui fonctionnera avec n’importe quel framework de test ( si votre classe n’est pas -final
) consiste à créer manuellement votre propre maquette.
Cela n’utilise aucun framework, donc il n’est pas aussi élégant, mais il fonctionnera toujours: même sans PowerMock. Sinon, vous pouvez utiliser Mockito pour effectuer les étapes 2 et 3 à votre place, si vous avez déjà effectué l'étape 1.
Pour simuler directement une méthode privée, vous devez utiliser PowerMock comme indiqué dans le autre réponse .
Pour une raison quelconque, la réponse de Brice ne fonctionne pas pour moi. J'ai été capable de le manipuler un peu pour le faire fonctionner. C'est peut-être juste parce que j'ai une version plus récente 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.anyString;
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", anyString(), anyInt());
classToTest.meaningfulPublicApi();
}
}
je connais un moyen ny que vous pouvez appeler votre fonction privée pour tester en 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);
}