web-dev-qa-db-fra.com

Mockito: se moquer d'un arraylist qui sera bouclé dans une boucle for

J'ai une méthode en cours de test qui contient l'extrait de code suivant:

private void buildChainCode(List<TracedPath> lines){
    for(TracedPath path : lines){
        /.../
    }
}

Mon code de test unitaire ressemble à ceci:

public class ChainCodeUnitTest extends TestCase {

    private @Mock List<TracedPath> listOfPaths;
    private @Mock TracedPath tracedPath;

    protected void setUp() throws Exception {
        super.setUp();
        MockitoAnnotations.initMocks(this);
    }

    public void testGetCode() {
        when(listOfPaths.get(anyInt())).thenReturn(tracedPath);

        ChainCode cc = new ChainCode();
        cc.getCode(listOfPaths);

        /.../
    }
}

Le problème est que lors de l'exécution du test, le code de test n'entre jamais dans la boucle for. Que faire lorsque les conditions doivent être spécifiées pour que la boucle for soit entrée? Actuellement, j'ai spécifié when(listOfPaths.get(anyInt())).thenReturn(tracedPath), mais je suppose qu'il n'est jamais utilisé.

21
Rebane Lumes

Votre problème est que lorsque vous utilisez une collection dans une boucle for-each, sa méthode iterator() est appelée; et vous n'avez pas écrasé cette méthode particulière.

Au lieu de se moquer de la liste, je vous recommande fortement de simplement passer une vraie liste, où les éléments ne sont que votre TracedPath moqué, autant de fois que vous le souhaitez. Quelque chose comme

listOfPaths = Arrays.asList(mockTracedPath, mockTracedPath, mockTracedPath);
57
Dawood ibn Kareem

La boucle Java For-Each utilisée dans votre méthode buildChainCode n'appelle pas get(), comme vous l'avez déjà compris - elle utilise la fonction iterator() méthode définie dans Collection<E>, lequel List<E> s'étend.

Je vraiment ne recommanderais pas de me moquer de la liste. Il n'y a aucun avantage, à moins que vous ne deviez absolument vérifier que la liste a été itérée, et même dans ce cas, il est préférable d'affirmer ou de vérifier les résultats du comportement de votre classe compte tenu de certaines entrées.

Passer une implémentation de List<E> comme LinkedList<E> avec tracedPath dedans.

6
Chris Mantle