2016-03-20 7 views
0

Ich habe eine Methode wie folgt.Wie Unit-Test die Interna dieser Methode

public static ArrayList<CustomDrinkIngredient> getCustomDrinkIngredient() { 

    ArrayList<CustomDrinkIngredient> customDrinkList = new ArrayList<>(); 
    Scanner scanner = new Scanner(System.in); 
    String userInput; 
    System.out.println("Please input ingredients per line with their quantity seperated by a comma. (q to quit)"); 

    while (true) { 
     userInput = scanner.nextLine(); 

     // Reread input if its empty, greater than 1 character or invalid 
     if (userInput.isEmpty()) { 
      System.out.println("Input is empty"); 
      continue; 
     } 
     if (userInput.charAt(0) == 'q') 
      break; 
     String[] input = userInput.split(","); 
     if (input.length != 2) { 
      System.out.println("Input is invalid"); 
      continue; 
     } 

     if (Ingredient.contains(input[0].toUpperCase()) == false) { 
      System.out.println("Ingredient is invalid"); 
      continue; 
     } 

     // Refactor with apache commons 
     input[1] = input[1].trim(); 
     if (isNumeric(input[1]) == false) { 
      System.out.println("Ingredient quantity is not numeric."); 
      continue; 

     } 
     if (!(Integer.parseInt(input[1]) > 0 && Integer.parseInt(input[1]) < 10)) { 
      System.out.println("Ingredient quantity is invalid. Should be less than 10."); 
      continue; 
     } 

     customDrinkList.add(
       new CustomDrinkIngredient(Ingredient.valueOf(input[0].toUpperCase()), Integer.parseInt(input[1]))); 

    } 

    scanner.close(); 
    return customDrinkList; 
} 

Die Fehlerprüfung ist innerhalb dieser Methode logisch aufgegliedert. Im Falle von fehlerhaften Daten wird jedoch nur auf der Konsole gedruckt und wiederholt, d. H. Keine Ausnahme ausgelöst oder wahr/falsch zurückgegeben.

Jetzt, wenn ich dies in verschiedenen Eingabeszenarien testen möchte, habe ich nur die allgemeine getCustomDrinkIngredient() -Methode, mit der als Ganzes zu interagieren.

Ich kann das System.in in meinem Komponententest wie folgt simulieren, indem ich einen ungültigen Eingang übergebe, aber alles, was ich bekomme, ist eine Ausgabe auf dem Bildschirm.

@Test 
    public void testGetCustomDrinkIngredient() { 
     String data = "Coffee, 1\nInvalidInput, 1\nq"; 
     InputStream stdin = System.in; 
     try { 
      System.setIn(new ByteArrayInputStream(data.getBytes())); 
      Scanner scanner = new Scanner(System.in); 
      ArrayList<CustomDrinkIngredient> ingredients = BaristamaticTest.getCustomDrinkIngredient(); 
      scanner.close(); 
     } finally { 
      System.setIn(stdin); 

     } 

    } 

Ich dachte an die Arraylist für null als Zeichen des Scheiterns prüft, aber das, was es genau Szenario scheiterte auf nicht genau feststellen würde.

Wie kann ich Komponententests für jedes einzelne Szenario erstellen?

Antwort

1

Betrachten Sie die Funktionsdeklaration auf die folgende Veränderung:

public static ArrayList<CustomDrinkIngredient> getCustomDrinkIngredient(
    ArrayList<CustomDrinkIngredient> customDrinkList, 
    PrintStream out, 
    String userInput) { ... your code ...} 

Diese Sie Unit-Test alle Szenarien ermöglichen, was ausgegeben wird, und dem, was die customDrinkList enthält. Sie übergeben nur die Objekte, nach denen Sie nach dem Aufruf der Funktion Assertionen machen. In Ihrem Produktionscode gäbe es eine Funktion, die dafür zuständig ist, Benutzereingaben zu wiederholen und diese Funktion mit einer ArrayList aufzurufen, in der Sie die Zutaten und "System.out" zusammen mit den echten Benutzereingaben sammeln.