2016-03-20 10 views
0

以下のメソッドがあります。このメソッドの内部を単体テストする方法

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; 
} 

エラーチェックは論理的にはこのメソッド内で行われます。しかし、データが誤っている場合は、単にコンソールに表示され、例外はスローされず、true/falseが返されます。

これをユニットテストするには、さまざまな入力シナリオで、一般的なgetCustomDrinkIngredient()メソッドを使用するだけです。

次のように私のユニットテストでSystem.inをシミュレーションして、無効な入力を渡すことができますが、返されるのは画面上の出力です。

@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); 

     } 

    } 

私はそれが失敗した正確などのシナリオ突き止めるないだろうと、失敗のマークとしてヌルのためのArrayListをチェックすると思ったが、。

個々のシナリオごとに単体テストを作成するにはどうすればよいですか?

答えて

1

を次のように関数宣言の変更を検討:

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

これは、ユニットテストに出力し、何customDrinkListが含まれているものについてのすべてのシナリオをあなたにできるようになります。関数を呼び出した後でアサーションを行うオブジェクトを渡すだけです。プロダクションコードでは、ユーザー入力をループし、この関数をArrayListで蓄積し、実際のユーザー入力に加えて 'System.out'を加えた関数があります。

関連する問題