Je veux créer une liste simulée pour tester le code ci-dessous:
for (String history : list) {
//code here
}
Voici ma mise en œuvre:
public static List<String> createList(List<String> mockedList) {
List<String> list = mock(List.class);
Iterator<String> iterHistory = mock(Iterator.class);
OngoingStubbing<Boolean> osBoolean = when(iterHistory.hasNext());
OngoingStubbing<String> osHistory = when(iterHistory.next());
for (String history : mockedList) {
osBoolean = osBoolean.thenReturn(true);
osHistory = osHistory.thenReturn(history);
}
osBoolean = osBoolean.thenReturn(false);
when(list.iterator()).thenReturn(iterHistory);
return list;
}
Mais lorsque le test est lancé, il lance une exception à la ligne:
OngoingStubbing<DyActionHistory> osHistory = when(iterHistory.next());
pour plus de détails:
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at org.powermock.api.mockito.PowerMockito.when(PowerMockito.Java:495)
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, you naughty developer!
Comment puis-je résoudre ce problème? Merci
OK, c'est une mauvaise chose à faire. Ne vous moquez pas d'une liste; au lieu de cela, mockez les objets individuels dans la liste. Voir Mockito: se moquant d'un arraylist qui sera bouclé dans une boucle for pour savoir comment faire cela.
Aussi, pourquoi utilisez-vous PowerMock? Vous ne semblez rien faire qui nécessite PowerMock.
Mais la vraie cause de votre problème est que vous utilisez when
sur deux objets différents, avant de terminer le stubbing. Lorsque vous appelez when
et que vous indiquez l’appel de méthode que vous essayez de remplacer, la prochaine action que vous effectuez dans Mockito OR PowerMock consiste à spécifier La méthode est appelée - c’est-à-dire faire la partie thenReturn
. Chaque appel à when
doit être suivi d’un seul et unique appel à thenReturn
avant de pouvoir effectuer d’autres appels. à when
. Vous avez fait deux appels à when
sans appeler thenReturn
- c'est votre erreur.
Lorsque je traite des listes moqueuses et les itère, j'utilise toujours quelque chose comme:
@Spy
private List<Object> parts = new ArrayList<>();
Nous pouvons nous moquer de la liste correctement pour une boucle foreach. Veuillez trouver ci-dessous l'extrait de code et l'explication.
Ceci est ma méthode de classe actuelle où je veux créer un scénario de test en moquant une liste. this.nameList
Est un objet de la liste.
public void setOptions(){
// ....
for (String str : this.nameList) {
str = "-"+str;
}
// ....
}
La boucle foreach fonctionne en interne sur un itérateur, nous avons donc créé ici un simulacre de itérateur. Le framework Mockito permet de renvoyer une paire de valeurs lors de l'appel d'une méthode particulière en utilisant Mockito.when().thenReturn()
, c'est-à-dire que hasNext()
passe le premier vrai et le second faux, de sorte que notre boucle ne continue que deux fois. fois. Sur next()
, nous renvoyons simplement la valeur de retour réelle.
@Test
public void testSetOptions(){
// ...
Iterator<SampleFilter> itr = Mockito.mock(Iterator.class);
Mockito.when(itr.hasNext()).thenReturn(true, false);
Mockito.when(itr.next()).thenReturn(Mockito.any(String.class);
List mockNameList = Mockito.mock(List.class);
Mockito.when(mockNameList.iterator()).thenReturn(itr);
// ...
}
De cette façon, nous pouvons éviter d’envoyer la liste réelle à tester en utilisant un modèle de liste.