2010-08-25 4 views
6

Comment utiliser EasyMock pour modifier un paramètre de méthode mutable de méthode mocked? Par exemple, j'ai une classe qui utilise une BlockingQueue. Je veux mocker le membre BlockingQueue pour les tests unitaires. Ma classe appelle la méthode queue.drainTo (Collection c). L'appel de cette méthode supprime des éléments de la file d'attente et les ajoute à la collection. Comment est-ce que je me moquerais de ce comportement en utilisant EasyMock? Les exemples seraient géniaux.EasyMock et modification d'un paramètre de méthode mutable

Répondre

0

difficile de dire exactement à quoi ressemble votre code. Pourriez-vous aider à mieux si je savais que le code que vous voulez tester .. mais en supposant que votre code que vous voulez tester ressemble à ceci:

private BlockingQueue<String> queue; 
private List<String> myList = new ArrayList<String>(): 

private void setBlockingQueue(BlockingQueue<String> queue) { 
    this.queue = queue; 
} 

public List<String> getMyList() { 
    return myList; 
} 

public void setMyList(List<String> myList) { 
    this.myList = myList; 
} 

public void doWork() { 
    System.out.println("blah"); 
    queue.drainTo(myList); 
} 

Un test serait

public void testDoWork() { 
    List<String> stuffToDrain = new ArrayList<String>(); 
    stuffToDrain.add("foo"); 
    stuffToDrain.add("bar"); 
    myTestingClass.setMyList(stuffToTrain); 


    BlockingQueue<String> queue = EasyMock.createMock(BlockingQueue.class ); 
    myTestingClass.setBlockingQueue(queue); 
    queue.drainTo(stuffToDrain); 
    EasyMock.replay(queue); 
    myTestingClass.doWork(); 
    EasyMock.verify(queue); 



} 

Désolé si ce n » t bon, mais vraiment difficile de suggérer un test pour le code que je ne peux pas voir ...

Éditer - nous ne pouvons pas vraiment affirmer que le paramètre mutable est changé en raison de la façon dont nous utilisons le faux. Tout ce que nous pouvons faire, c'est affirmer que la méthode drainTo est appelée. Si drainTo fait ce que nous voulons faire devrait être testé ailleurs .. c'est-à-dire dans les tests de BlockingQueue.class

Édition 2 - nous pouvons être plus précis sur la liste avec laquelle nous attendons que la méthode soit appelée.

+0

Désolé de ne pas poster de code, mais votre «myTestingClass» ressemble à ce que je recherche. Je regarde votre code de test. Comment la liste stuffToDrain a-t-elle été ajoutée à myList en exécutant ce test? –

+0

Il ne sera pas ajouté à la liste. Vous ne pouvez pas tester ça ici. Vous devez tester cela dans un test séparé .. (ou parce que BlockingQueue fait partie de Java, vous supposez juste qu'il est correct et ne le teste pas) – bwawok

+0

ok, est-il possible de faire modifier un paramètre mutable par EasyMock? ? –

12

Vous pouvez utiliser andAnswer et getCurrentArguments:

public void testDrainToQueue() { 
    BlockingQueue<Foo> queue = EasyMock.createMock(BlockingQueue.class); 
    EasyMock.expect(queue.drainTo(EasyMock.isA(List.class))) 
     .andAnswer(new IAnswer<Integer>() { 
     public Integer answer() { 
      ((List) EasyMock.getCurrentArguments()[0]).add(new Foo(123)); 
      return 1; // 1 element drained 
     } 
     }); 
    EasyMock.replay(queue); 
    ... 
} 

Il aide parfois à extraire une classe d'aide ou d'une méthode:

private static IAnswer<Integer> fakeDrainReturning(final List drainedElements) { 
    return new IAnswer<Integer() { 
    @Override public Integer answer() { 
     ((List) EasyMock.getCurrentArguments()[0]).addAll(drainedElements); 
     return drainedElements.size(); 
    } 
    }; 
} 

Ensuite, vous pouvez faire:

List<Foo> drainedElements = Arrays.asList(new Foo(123), new Foo(42)); 
EasyMock.expect(queue.drainTo(EasyMock.isA(List.class))) 
    .andAnswer(fakeDrainReturning(drainedElements)); 

Il pourrait mieux vaut utiliser un vrai BlockingQueue et trouver un moyen d'insérer La valeur souhaitée dans la file d'attente avant la méthode que vous prévoyez de supprimer des données de la file d'attente.

Questions connexes