2017-07-03 6 views
-1

Wie rufe ich die populateMapWithFormattedDates-Methode in JUnit auf und wie schreibe ich JUnit populateMapWithFormattedDates für diese Methode. Ich weiß nicht, wie man JUnit für verschachtelte Methoden schreibt, also bitte helfen.Wie schreibe ich Junit für diesen Code?

protected Map<String, String> populateDispatch(final RequestDispatchData requestDispatchData) 
    { 
     final Map<String, String> map = getDispatchFieldMapper().populateMapper(requestDispatchData); 
     populateMapWithFormattedDates(requestDispatchData, map); 
} 


private void populateMapWithFormattedDates(final RequestDispatchData requestDispatchData, final Map<String, String> map) 
    { 
     String dateFormatted = map.get("ticket_date"); 
     Date date = null; 
     try 
     { 
      date = new SimpleDateFormat("MM/dd/yy").parse(dateFormatted); 
     } 
     catch (ParseException parseException) 
     { 
      customLogger.logMessage(diagnosticMethodSignature, DiagnosticType.EXCEPTION, 
        "Exception in parsing start date of ticket " + parseException); 
     } 
     map.put("startDateDDMMYY", DateEnum.DDMMYY.getFormattor().format(date)); 
     map.put("startDateDDMMMYY", DateEnum.DDMMMYY.getFormattor().format(date)); 
     map.put("startDateDMY", DateEnum.DMY.getFormattor().format(date)); 
     map.put("startDateYYMMDD", DateEnum.YYMMDD.getFormattor().format(date)); 
    } 
+1

Wenn Sie wissen, was 'private' Stichwort tut, müssen Sie Sie wissen, dass Sie 'populateMapWithFormattedDates' in Ihrer Testklasse nicht aufrufen können. Sie müssen Tests für 'populateDispatch' schreiben, die alle von ihr aufgerufenen privaten Methoden testen. – Mritunjay

+1

Die Theorie, die ich bevorzuge, ist, dass Unit-Tests das öffentlich sichtbare Verhalten einer Klasse testen sollten, was bedeutet, dass man Unit-Tests für private Methoden nicht schreiben sollte. – ajb

Antwort

0

Es gibt nichts wie eine verschachtelte Methode in Java. Es ist ein verschachtelter Funktionsaufruf, was es ist. Plus, yea, Sie können die privaten Funktionen einer Klasse nicht über ihr Objekt aufrufen, daher ist es nicht möglich, sie einzeln zu testen, indem Sie sie aufrufen.

Sie können, obwohl eine öffentliche oder geschützte Funktion den Aufruf etwas wie ein Getter haben.

0

Ich glaube, Ihr Code etwas ist, was wie,

protected Map<String, String> populateDispatch(final RequestDispatchData requestDispatchData) 
    { 
     final Map<String, String> map = getDispatchFieldMapper().populateMapper(requestDispatchData); 
     return populateMapWithFormattedDates(requestDispatchData, map); 
} 

beachten Sie, dass Sie die return-Anweisung verpasst haben, und aktualisieren Sie die Karte auf bestimmte Bedingung aus,

private void populateMapWithFormattedDates(final RequestDispatchData requestDispatchData, final Map<String, String> map) 
    { 
// Map manipulation here 
} 

Also, wenn Sie mindestens haben Abhängigkeit von der getDispatchFieldMapper(). populateMapper(), dann können Sie populateDispatch() direkt aus Ihrem Testcode aufrufen, sonst müssen Sie möglicherweise eine Möglichkeit finden, ein custo zu injizieren m Implementierung von DispatchFieldMapper zur Vorbereitung der Map zum Testen Ihrer Zielmethode.

Injektion von DispatchFieldMapper kann über das Überschreiben der getDispatchFieldMapper() oder verwenden Sie eine setDispatchFieldMapper() auf Ihrer Klasse sein.

Während Ihre individuellen DispatchFieldMapper vorbereitet, stellen Sie sicher, dass der populateMapper() eine Karte mit allen Daten zurückgibt für Ihre Tests erforderlich.

0

Es ist keine gute Idee, beim Test direkt aus der Testklasse eine nicht zugängliche Methode aufzurufen.
Zweite Sache: Nicht zugreifbare Methode wird immer Form irgendeiner zugreifbaren Methode oder Bereich genannt, sonst ist Code toter Code, entfernen Sie das einfach.

Weil Methode ist Liguster, also, wenn es in Gebrauch ist, dann rief es irgendwo vom Code der gegenwärtigen Klasse an. in Ihrem Code nannte es Formular populateDispatch, so ist die tatsächliche Art und Weise zu schreiben Testfall für populateMapWithFormattedDates Methode ist Abdeckung aller Szenarien für populateDispatch Methode und populateDispatch wird auch verwendet Form Unterklasse der aktuellen Klasse nennen es Form dort.

Aber Sie können wie private Methode in junit nennen:

Deencapsulation.invoke(<object of class in called method is exist>, "populateMapWithFormattedDates", <object of RequestDispatchData class>, <object of Map<String, String> class>); 

Wieder ist es eine Möglichkeit, private Methode zu nennen, aber Sie sollten nicht verwenden ...

1

Ganz einfach: Sie prüfen nicht private Methoden direkt.

Stattdessen konzentrieren Sie sich auf den "öffentlichen Vertrag" jener Methoden, die "von außen" aufgerufen werden.In Ihrem Fall wäre, dass sein:

Map<String, String> populateDispatch(... 

So mögen Sie Tests schreiben wie:

@Test 
public void populateDispatchForValidDate() { 
    RequestDispatchData request = ... 
    Map<String, String> actualOutput = underTest.populateDispatch(request); 
    assertThat(actualOutput.size(), is(5)); 
} 

oben The ist nur als Beispiel gedacht. Was es bewirkt:

  • erstellen Sie ein "Anfrage" -Objekt. Dies könnte ein Spott sein; oder ein reales Objekt - hängt davon ab, was genau Ihre verschiedenen Methoden mit diesem Objekt machen. Und wie einfach ist es, mit „Testdaten“
  • es ruft ein „echtes“ RequestDispatchData Objekt zu erstellen, diese Methode im Test
  • es eine/mehrere Eigenschaften des Ergebnisses behauptet kommen zurück

Suche Bei Ihrem Produktionscode macht dieser Code viel zu viele Dinge innerhalb dieser einzelnen Methode. Vielleicht möchten Sie etwas über "sauberen Code" lesen und diesen Code verbessern. Dies führte wahrscheinlich zur Schaffung einiger Hilfsklassen, die dann leichter zu testen wären.

0

Sie sollten die populateMapWithFormattedDates Methode wie folgt entkoppeln:

// I created an utility class but it's a suggestion. 
// I'm using an util class because you don't use requestDispatchData for 
// anything. But if you do, maybe it's a good idea to implement this code 
// on RequestDispatchData class 
class DispatchMapUtils { 
    // Note that I took of the requestDispatchData 
    public static Map<String, String> populateMapWithFormattedDates(final Map<String, String> map) throws ParseException { 
     // Your code without try-catch. 
     // Throw the exception to the caller of this method 
     // and try-catch there to use the customLogger 
    } 
} 

Mit diesem Code, würde Ihr Test so etwas wie dieses:

@Test 
public void shouldFormatTicketDateInVariousFormat() { 
    Map<String, String> map; 
    // Instantiate and put some initial datas 
    map = new ... 
    map.put('ticket_date') = .. 
    // Call the method! 
    DispatchMapUtils.populateMapWithFormattedDates(map); 
    // Do the assertions! 
    Assert.assertTrue(map.get("startDateDDMMYY").equals(...)); 
} 

@Test 
public void shouldThrowExceptionWhenTicketDateIsInvalid() { 
    // More testing code 
}