以下のメソッドがあります。このメソッドの内部を単体テストする方法
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をチェックすると思ったが、。
個々のシナリオごとに単体テストを作成するにはどうすればよいですか?