JUnit测试-如何检查扫描仪是否存在各种输入不匹配

时间:2018-07-18 04:59:57

标签: java testing input junit

我正在尝试为将华氏度转换为摄氏度(以及相反)的程序编写JUnit测试。所以我的课看起来像:

package asdf;

import java.util.Scanner;

public class UnitTesting {

    public UnitTesting()
    {

    }

    public int returnInt()
    {
        Scanner scanner = new Scanner(System.in);
        int x = scanner.nextInt();
        return x;
    }

    public double returnDouble()
    {
        Scanner scanner = new Scanner(System.in);
        double x = scanner.nextDouble();
        return x;
    }

    public double convertCtoF(double c) {
        return 1.8*c+32;
    }

    public double convertFtoC(double f) {
        return (5.0/9.0*(f-32));
    }

    public void menu()
    {
        int a;
        do {
            System.out.println("1 - convert C degrees to F degrees");
            System.out.println("2 - convert F degrees to C degrees");
            System.out.println("0 - exit");
            a = returnInt();
            switch(a)
            {
            case 1:
                System.out.println(convertCtoF(returnDouble()));
                break;
            case 2:
                System.out.println(convertFtoC(returnDouble()));
                break;
            case 0:
                System.out.println("Bye!");
                break;
            default:
                System.out.println("Choose 1, 2 or 0");
                break;
            }
        }
        while(a!=0);
    }

    public static void main(String [] args)
    {
        UnitTesting ut = new UnitTesting();
        ut.menu();
    }
}

测试课程:

package asdf;

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

class UnitTestingTests {

    private UnitTesting ut;

    @BeforeEach
    public void init() {
    ut = new UnitTesting();
    }

    @Test
    void checkIfInputMismatch() {
        ut.returnDouble();
        //some_kind_of_assert
    }

}

由于我想测试用户输入的各种不匹配异常(NumberFormat,InputMismatch等),但是我不知道这种方法是否可以用于当前方法returnDouble()returnInt()。我当时正在考虑将扫描仪更改为以字符串(nextLine)形式读取输入,但是随后需要额外的解析方法。

需要什么来改变方法/类以检查输入是否是数字或用户给出的格式是否正确?

谢谢

3 个答案:

答案 0 :(得分:1)

一些常见的技术包括:

  • 将用户交互和程序逻辑(此处为温度转换)分离为单独的类。单独对逻辑进行单元测试。通常,不对用户交互进行单元测试,而是对包括用户交互的整个程序进行集成测试(为此,您可以使用JUnit或其他工具)。
  • 每次阅读输入内容时都不要创建新的Scanner。始终使用相同的Scaner。在这种情况下,为了测试目的,注入从Scanner以外的其他来源读取的System.in并不难(如果您真的坚持要创建一个新的Scanner,则可以有一种方法,该方法在生产中创建一个从Scanner读取的System.in,在测试中创建一个从其他来源读取的方法;但是正如我所说的,不要打扰)。
  • 您也可以将System.in设置为键盘以外的其他输入流,以进行测试。和/或类似地将System.out重新布线到另一个输出流,该流可以测试写入其中的内容。

答案 1 :(得分:1)

我创建了一个库System Rules,该库提供了填充System.in和读取System.out的输出的规则。您的测试可能如下所示:

package asdf;

import static org.junit.Assert.*;

import org.junit.Test;

public class UnitTestingTests {
    @Rule
    public final TextFromStandardInputStream systemInMock
        = emptyStandardInputStream();

    private UnitTesting ut;

    @Test
    void checkIfInputMismatch() {
        systemInMock.provideLines("1.23");

        double value = ut.returnDouble();

        //some_kind_of_assert
    }
}

不幸的是,系统规则仅支持JUnit4。我正在研究系统规则的独立于测试框架的替代方案。

答案 2 :(得分:1)

要控制输入为整数,双精度或无效输入,您需要将输入作为字符串。然后,您可以使用包装器类的已定义解析方法。

package asdf;

import java.util.Scanner;

public class UnitTesting {

    public int returnInt()
    {
        Scanner scanner = new Scanner(System.in);
        String s = scanner.nextLine();
        try{
            int x = Integer.parseInt(s);
            return x;
        }catch(NumberFormatException ex){ // handle your exception, there you can give some messages to user.
            System.out.println("The input is invalid for integer.");
        }
    }

    public double returnDouble()
    {
        Scanner scanner = new Scanner(System.in);
        String s = scanner.nextLine();
        try{
            double x = Integer.parseDouble(s);
            return x;
        }catch(NumberFormatException ex){ // handle your exception, there you can give some messages to user.
            System.out.println("The input is invalid for double.");
        }
    }

    public double convertCtoF(double c) {
        return 1.8*c+32;
    }

    public double convertFtoC(double f) {
        return (5.0/9.0*(f-32));
    }

    public void menu()
    {
        int a;
        do {
            System.out.println("1 - convert C degrees to F degrees");
            System.out.println("2 - convert F degrees to C degrees");
            System.out.println("0 - exit");
            a = returnInt();
            switch(a)
            {
            case 1:
                System.out.println(convertCtoF(returnDouble()));
                break;
            case 2:
                System.out.println(convertFtoC(returnDouble()));
                break;
            case 0:
                System.out.println("Bye!");
                break;
            default:
                System.out.println("Choose 1, 2 or 0");
                break;
            }
        }
        while(a!=0);
    }

    public static void main(String [] args)
    {
        UnitTesting ut = new UnitTesting();
        ut.menu();
    }
}

另一种控制方式:模式匹配

String input=...;
String pattern ="-?\\d+";
if(input.matches("-?\\d+")){ // any positive or negetive integer or not!
 ...
}