2016-11-18 3 views
0

Ich bin neu in JUnit, und weiß nicht, welche Methoden Tests haben sollten und welche nicht. Nehmen Sie das folgende Beispiel:Für welche Methoden sollte ich JUnit testen - Wie man Methoden mit vielen Abhängigkeiten vortäuscht

public List<Site> getSites(String user) 
{ 
    SiteDao dao = new SiteDaoImpl(); 
    List<Site> siteList = new ArrayList<Site>(); 
    ServiceRequest rq = new ServiceRequest(); 
    rq.setUser(user); 

    try 
    { 
     ServiceResponse response = siteDAO.getReponse(rq); 
     List<String> siteNums = response.getSiteNums(); 

     if (siteNums != null && !siteNums.isEmpty()) 
     { 
      List<DbModelSite> siteInfo = dao.getSiteInfo(siteNums); 

      if (siteInfo != null && !siteInfo.isEmpty()) 
      { 
       siteList = SiteMapper.mapSites(siteInfo); 
      } 
     } 
    } 
    catch (Exception e) 
    { 
     e.printStackTrace(); 
    } 

    return siteList; 
} 


public static List<Site> mapSites(List<DbModelSite> siteInfo) 
{ 
    List<Site> siteList = null; 

    if (siteInfo != null && !siteInfo.isEmpty()) 
    { 
     siteList = new ArrayList<Site>(); 

     for (DbModelSite temp : siteInfo) 
     { 
      Site currSite = mapSite(temp); 
      siteList.add(currSite); 
     } 
    } 

    return siteList; 
} 


public static Site mapSite(DbModelSite site) 
{ 
    Site mappedSite = null; 

    if (site != null) 
    { 
     mappedSite = new Site(); 

     mappedSite.setSiteNum(site.getSiteNum()); 
     mappedSite.setSpace(site.getSpace()); 
     mappedSite.setIndicator("Y"); 
    } 

    return mappedSite; 
} 

Es ziemlich trivial ist mit einem Unit-Test zu kommen sowohl für die mapSites() und mapSite() Methoden, aber wo ich Probleme mit dem getSites() Verfahren. Ist es sinnvoll, diese Methode zu testen? Wenn ja, wie würde ich das tun? Es scheint, dass dies ziemlich viel Verspottung erfordern würde, und da ich für JUnit sehr neu bin, war ich nicht in der Lage herauszufinden, wie man all diese Objekte verspotten sollte.

Also meine Frage ist wirklich zweifach:

  1. Wie bestimmen Sie, ob eine Methode Einheit getestet werden muss?
  2. Wie testet eine Einheit eine komplexe Methode, die viel Spott verlangt?
+0

Ja, es sollte auch Unit-getestet sein, idealerweise sollten mindestens alle "öffentlichen" Methoden Unit-getestet sein, da sie irgendwie den Vertrag Ihrer Anwendung definieren –

Antwort

3

Ja, es ist sinnvoll, diese Methode zu testen.

Die erste Sache, um es zu testen, wäre die Abhängigkeitsinjektion. Wenn die Methode mithilfe von new eine eigene SiteDao-Instanz erstellt, können Sie der Methode nicht mitteilen, eine andere Instanz von SiteDao zu verwenden.

Also, lesen Sie auf Abhängigkeitsinjektion, und verwenden Sie es. Im Grunde läuft es bis auf

public class MyService { 

    private SiteDao siteDao; 

    public MyService(SiteDao siteDao) { 
     this.siteDao = siteDao; 
    } 

    // use the siteDao passed when constructing the object, instead of constructing it 
} 

diese Weise, wenn Ihr Service zu testen, können Sie

SiteDao mockSiteDao = mock(SiteDao.class); 
SiteService service = new SiteService(mockSiteDao); 

Hier ist ein Stück von Beratung tun, die nicht direkt auf Ihre Frage bezieht, sondern wird Ihr Code machen viel einfacher und damit auch einfacher zu testen:

  1. Geben Sie niemals null von einer Methode zurück, die eine Auflistung zurückgibt. Eine leere Sammlung zurückgeben, um "kein Element" zu signalisieren.
  2. Im Allgemeinen akzeptieren Sie null nicht als gültigen Methodenargumentwert, insbesondere wenn das Argument eine Auflistung ist.
  3. Korollar von 1 und 2: Wenn Sie diesen Prinzipien folgen, müssen Sie nie auf Null oder Leerheit einer Sammlung prüfen. Benutze es einfach direkt.

Dies wird die Anzahl der if (siteNums != null && !siteNums.isEmpty()) unübersichtlich Code zu reduzieren, und Sie werden Art und Weise weniger Verzweigungen haben zu testen.

Beachten Sie, dass alle vernünftigen Bibliotheken (JDK-Methoden, JPA usw.) diesen Prinzipien folgen. Eine JPA-Abfrage gibt beispielsweise niemals eine Nullliste zurück.

Schlucken Sie auch keine Ausnahme, indem Sie nur ihre Stack-Trace drucken und eine leere Liste zurückgeben, als ob nichts Schlimmes passiert wäre. Lassen Sie die Ausnahme propagieren, damit Sie den Fehler bemerken und beheben können.

Stellen Sie sich vor, dass diese Methode eine Methode ist, mit der die Anzahl der Krebstumore ermittelt wird, die von einem medizinischen Analysesystem gefunden wurden. Möchten Sie wirklich, dass das System Ihnen sagt, dass Sie vollkommen gesund sind, während das System aufgrund einer Ausnahme tatsächlich nicht in der Lage war, seinen Job zu erledigen? Ich würde wirklich bevorzugen, dass das System sagt: "Ich bin außer Betrieb, benutze eine andere Maschine, um sicher zu sein".

+0

Vielen Dank! Sehr hilfreich. Soweit das bei der Nullkontrolle geht, macht das Sinn wenn sie meine Methoden sind, nehmen aber zum Beispiel 'siteNums'. Dies wird von einem externen Dienst zurückgegeben, so dass ich nicht weiß, ob sie genügend Null-Checks haben, also möchte ich die Antwort auf meiner Seite überprüfen, nur für den Fall, dass ich eine Null von diesem Service bekomme. Ich habe den Großteil der Ausnahmelogik genommen, um meinen Beitrag kürzer zu machen, aber hilfreiche Ratschläge. – mwelk11

+0

Es wurde von ServiceResponse zurückgegeben, das von SiteDao zurückgegeben wurde und von dem ich erwarte, dass es sich um Ihre Klassen handelt. Diese Klassen sollten denselben Regeln folgen. –

0

Die Idee der Komponententests ist sicherzustellen, dass jede "Einheit" (die in der Regel eine Methode ist) isoliert getestet werden kann, so dass Sie für eine gegebene Eingabe eine erwartete Ausgabe testen können, um Ihre Fragen zu beantworten:

  1. sollte ich alle öffentlichen Methoden sagen sollte sein Einheit
  2. getestet Wenn Sie in Ihrer Methode zu viel zu tun, die Sie brauchen viel zu verspotten dann haben Sie wahrscheinlich die Funktionalität heraus in eine andere Klasse
  3. brechen wollen

Gehen wir zurück zu Ihrem Beispiel gibt es ein paar Dinge, vorsichtig zu sein, wenn Sie Unit-Test wollen:

  • new - wann immer Sie dieses Schlüsselwort in einem Verfahren verwenden, werden Sie es schwierig finden, das Objekt zu verspotten. In einigen Fällen (wie ServiceRequest) ist es in Ordnung, aber in anderen wie SiteDao werden Sie Probleme haben.
  • Statische Methoden - Gleiche, mit SiteMapper.mapSites(siteInfo) Sie es schwierig finden

Sie können Bibliotheken wie PowerMock zu verspotten new, private und static Methoden verspotten, aber ich versuche persönlich das zu vermeiden.

Verwandte Themen