2017-05-16 1 views
0

Ich habe eine Klasse, die nur Aufgabe ist, eine List<Object> nehmen und eine sortierte List<Object> zurückgeben. Für ein Beispiel arbeitet die Sortiermethode in der Klasse mit einer Prozedur, die die Objekte zufällig in der Liste platziert.Komponententest für eine zufällige Liste <Object>

Der Versuch zu tun:, um den Test für diese Sortiermethode (oder Klasse) zu schreiben, die fehlschlagen muss, wenn die Sortierung tatsächlich nur zufällig ist. Das heißt, ich muss die List<Object> Reihenfolge finden, um zu testen, nehme ich an.

Code

class RootLoggerFirstSorter { 

List<LoggerConfig> sort(List<LoggerConfig> unSortedList) { 

    List<LoggerConfig> levelSortedList = new ArrayList<>(unSortedList); 

    Collections.sort(levelSortedList, new Comparator<LoggerConfig>() { 
     @Override 
     public int compare(LoggerConfig o1, LoggerConfig o2) { 
      if (o1.getLevel().intLevel() == o2.getLevel().intLevel()) { 
       return 0; 
      } else if (o1.getLevel().intLevel() < o2.getLevel().intLevel()) { 
       return 1; 
     } else { 
      return -1; 
     } 
    }} 
    ); 

    LinkedList<LoggerConfig> sortedList = new LinkedList<LoggerConfig>(); 
    for(Iterator<LoggerConfig> i = levelSortedList.iterator(); i.hasNext();) { 
     LoggerConfig cfg = i.next(); 
     addNextLoggerConfig(cfg, sortedList); 
    } 
    return sortedList; 
} 

private void addNextLoggerConfig(LoggerConfig cfg, LinkedList<LoggerConfig> sortedList) { 

    if(cfg.getName() == null || cfg.getName().isEmpty()) { 
     sortedList.addFirst(cfg); 
    } else { 
     sortedList.addLast(cfg); 
    } 
} 
} 

..... 
    expect(item1.getLevel()).andStubReturn(Level.DEBUG); 
    expect(item2.getLevel()).andStubReturn(Level.ERROR); 
    expect(item3.getLevel()).andStubReturn(Level.INFO); 
    ..... 
//Ignore the pre req for test setup 
    @Test 
public void testSort() { 

    List<LoggerConfig> unsortedList = makeUnsortedList(); 
    EasyMock.replay(item1,item2,item3); 

    List<LoggerConfig> sortedList = tested.sort(unsortedList); 

    assertThat("First item on the list is ERROR level: ", sortedList.get(0).getLevel(), is(Level.ERROR)); 
    assertTrue(sortedList.get(1).getLevel().equals(Level.INFO) || sortedList.get(1).getLevel().equals(Level.INFO)); 
    assertTrue(sortedList.get(2).getLevel().equals(Level.DEBUG) || sortedList.get(2).getLevel().equals(Level.DEBUG)); 
} 

Aber dieser Test wird immer da nur, wenn schaute 1 am Index passieren Versuchte getestet werden und 2, Index 0 immer enthalten LoggerConfig mit einem leeren Namen [eingerichtet ist so gemacht]). Also dachte ich Sollte ich nur Unit-Test die Vergleichsmethode stattdessen? Wenn ja, wie?

Problem Das Problem ist, dass ich die Sortiermethode mit einer bestimmten Object-Eigenschaft, die die Ebene des LoggerConfig Objekts ist, testen muss. Also muss der Test die List Bestellung überprüfen.

+1

Entweder Ihre Frage ist verwirrend oder es ist nur ich ... Was genau ist das Problem? Normalerweise würden Sie für jeden Testfall eine Testmethode schreiben, zum Beispiel "Liste in umgekehrter Reihenfolge sollte korrekt sortiert sein". In dieser Methode bereiten Sie die Liste vor, sortieren sie und überprüfen dann die Reihenfolge ... Ich verstehe nicht ganz, wo Sie Probleme haben ... –

+0

@FlorianSchaetz Da ich die Integer-Werte der Log-Level nicht kenne, die in verwendet werden das Sortieren muss ich herausfinden, um erfolgreich zu testen. Allerdings sollte der Test natürlich noch prüfen, ob die Sortierung erfolgt ist. Daher sind zwei Tests erforderlich. So testet mein 'testSort()' nicht die beabsichtigte Funktionalität, die eine geordnete Liste und nicht zufällig zurückgeben muss. – shaz

+0

Immer noch verwirrt. Wenn Sie die Protokollebenen kennen müssen, schauen Sie in den Code. Sollte dort angegeben werden. In Ihrem Test ist es völlig in Ordnung, sich darauf zu verlassen, dass der Loglevel beispielsweise 700 ... –

Antwort

0

Soll ich stattdessen einfach die Vergleichs-Methode testen?

Nein, sollten Sie nicht. Der Test kann fehlschlagen, wenn Sie versuchen, die Sortiermethode später zu refaktorieren. Sie versuchen tatsächlich zu behaupten, dass die Sortierung wahrscheinlich erfolgt ist. Die Vergleichsmethode ist nur ein Implementierungsdetail. Sie können die Vergleichs-Methode nicht verwenden, um die Liste in Zukunft zu sortieren.

Natürlich müssen Sie auch die integrierte Sortiermethode nicht testen, da Sie tatsächlich Ihre benutzerdefinierte Sortiermethode testen. Alles, was in dieser Sortiermethode enthalten ist, sind Implementierungsdetails, einschließlich der list.sort-Methode, die Sie aufgerufen haben. Sie sollten so tun, als ob Sie nichts davon wissen, wenn Sie einen Test schreiben.

Abgesehen davon enthält Ihre Sortiermethode auch eine Logik, die nicht mit der integrierten Sortiermethode zusammenhängt.

0

Ich nahm an, die List<ConfigLogger> folgte etwas wie item1["", ERROR], item2["com.fwk.foo", DEBUG], item3["com.fwk.core.baa", INFO]. In diesem Fall musste ich prüfen, ob sich Element3 in Position 1 befindet und Element2 in Position 3 in der Liste steht. Die Implementierung führt die Sortierung korrekt aus. So Test, den ich brauchte, war wie folgt:

@Test 
    public void testSort() { 
    List<LoggerConfig> unsortedList = makeUnsortedList(); 
    EasyMock.replay(item1,item2,item3); 

    List<LoggerConfig> sortedList = tested.sort(unsortedList); 

    assertFalse(unsortedList.equals(sortedList)); 
    assertTrue(sortedList.get(0).getName().isEmpty()); 

    LoggerConfig cfg1 = sortedList.get(1); 
    LoggerConfig cfg2 = sortedList.get(2); 

    assertThat(cfg1.getLevel(), is(Level.DEBUG)); 
    assertThat(cfg2.getLevel(), is(Level.INFO)); 
} 

Also habe ich das Element aus der Liste am Zugriff auf und zu vergleichen, wenn sie gleich sind wie erwartet.

1

Viele verschiedene Aspekte hier:

  • Natürlich brauchen Sie nicht zu testen, die Einbau- Collections.sort() -Methode.
  • In diesem Sinne: Stattdessen möchten Sie zwei Aspekte testen A), dass Sie tatsächlich diese Sortiermethode B) aufrufen, dass Ihr Komparator wie erwartet funktioniert.

A) wird durch den Code erreicht, den Sie in Ihre eigene Antwort eingeben. Oder um genau zu sein: Sie nur benötigen einen Testfall, bei dem Sie nach einem erwarteten Ergebnis sortieren; nachdem Sie Ihrer Methode eine spezifische Testeingabe bereitgestellt haben.

B) durch das Schreiben Testcode erreicht wird, die einfach überprüft, ob compareTo()

Am Ende das erwartete Ergebnis für die verschiedenen Eingangszurückgibt, ist dies über richtig Ihre Logik in Klassen zu sezieren. Natürlich können Sie diesen Komparator als anonyme innere Klasse deklarieren; Überprüfen Sie, ob die Sortiermethode das erwartete Ergebnis zurückgibt.

Aber wenn Sie den Komparator machen, sagen Sie irgendwo eine innere Klasse, könnten Sie Komponententests nur für die Komparatorfunktionalität schreiben.

Schließlich: Ihr Testfall tut nicht das Ziel bedeutet, dass Sie angegeben: muss fehlschlagen, wenn die Sortierung in der Tat ist nur zufällig. Sie sehen, wenn das Ergebnis von sort() ist zufällig, dass es zufällig geben Sie ein korrektes Ergebnis. Bedeutung: Sie können nicht erwarten, dass ein einzelner Test "möglicherweise zufälliges Verhalten" verifiziert. Sie müssten viele Tests mit vielen verschiedenen Daten ausführen und sicherstellen, dass alle von ihnen übergeben werden; um eine bestimmte Vertrauen zu erreichen, dass die Sortierung() ist nicht rein zufällig.

Aber wie gesagt: Sie sortieren nicht. Sie rufen die integrierte Sortiermethode auf, die nicht getestet werden muss.

Verwandte Themen