如何对这种方法的内部进行单元测试

时间:2016-03-20 01:21:21

标签: unit-testing junit refactoring junit4

我有一个方法如下。

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检查为null作为失败的标记,但是,这并不能确定它失败的确切场景。

如何为每个场景创建单元测试?

1 个答案:

答案 0 :(得分:1)

考虑将函数声明更改为以下内容:

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

这将允许您对输出内容和customDrinkList包含的内容进行单元测试。您只需传入调用函数后将进行断言的对象。在您的生产代码中,将有一个函数负责循环用户输入并使用ArrayList调用此函数,您的累积成分和&#39; System.out&#39;加上真实的用户输入。