2010-11-24 25 views
2

Comment tester l'unité le morceau de code suivant:Comment faire des tests unitaires sortie immédiate de la méthode

 
@Override 
public void update() { 
    if (isStopped() || isPaused()) { 
    return; 
    } 
    // ... 
} 

Cette méthode est à partir d'un flux audio. Il doit être appelé régulièrement pour que le flux lise les nouvelles données. Si la lecture est arrêtée ou en pause, le flux ne devrait pas avancer, donc je reviens immédiatement. Cependant, je ne peux pas trouver un moyen d'écrire un test pour ce code.

+0

Nous devons voir plus avant que cette méthode change pas d'état visible - si quelles variables d'instance sont là et que font isStopped et isPaused? – Mark

+1

Valide que quel que soit le '// ... ', n'est pas arrivé? –

+0

La couverture totale des tests unitaires est difficile à réaliser et ne vaut probablement pas la peine. À moins qu'il y ait quelques interactions géniales, cela ressemble à un cas que vous pourriez mettre dans le panier «trop dur». –

Répondre

1

Peut-être retourner un boolean indiquant ce qui s'est passé?

1

Dans ce cas, vous devez tester qu'il n'y a pas d'effets secondaires à l'appel de la méthode. Par exemple, si le ... a un appel de méthode sur un collaborateur, vous devez vous moquer de ce collaborateur, puis vérifier qu'aucune méthode sur le collaborateur n'a été appelée.

Vous pourriez également être en mesure de vérifier que les propriétés de l'objet sur lequel la mise à jour est appelé ne sont pas modifiées, en fonction de ce qui est réellement dans votre classe ....

0

est ici une approche compliquée:

Une idée serait d'implémenter le modèle Observer, de définir une interface d'écoute qui peut s'abonner aux événements de votre classe testée. l'événement serait dans ce cas, être envoyé après le bloc if:

public interface EventListener{ 
    // EventDetails would be an object that encapsulates 
    // event type and extra data 
    void process(EventDetails type); 
} 


private void dispatchEvent(EventType type){ 
    for(EventListener listener : this.listeners){ 
     listener.process(new EventDetails(type 
      /* you'll want to add more data than that here */)); 
    } 
} 


@Override 
public void update() { 
    if (isStopped() || isPaused()) { 
    return; 
    } 
    dispatchEvent(EventType.UPDATE); 
    // ... 
} 

Et dans la classe de test:

yourClass.addEventListener(new EventListener(){ 
    public void process(EventDetails details){ 
     if(EventType.UPDATE.equals(details.getEventType())){ 
      fail("Received update event"); 
     } 
    } 
}); 
// set to stopped or paused 
yourClass.update(); 
// if we got here, test has succeeded 

Bien sûr, cette approche est une énorme intrusion dans la façon dont les choses fonctionnent maintenant et cela n'a de sens que si votre application peut réellement utiliser un système de notification d'événements (la capacité de test de l'unité n'est qu'un bel effet secondaire).


Ou quelque chose de complètement différent:

dans le test unitaire, utilisez une sous-classe qui l'emporte sur toute autre méthode est appelée après la si bloc.

Alors disons que le code d'origine est la suivante:

@Override 
public void update() { 
    if (isStopped() || isPaused()) { 
    return; 
    } 
    doUpdate(); 
} 

alors la sous-classe emporterait sur la méthode doUpdate():

protected void doUpdate(){ 
    fail("I shouldn't be here"); 
}