Java JUnit测试-如何检查扫描仪的各种输入不匹配

Java JUnit测试-如何检查扫描仪的各种输入不匹配,java,testing,input,junit,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);

我正在尝试为一个程序编写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),但随后需要额外的解析方法。需要什么来改变方法/类来检查输入是否是一个数字,或者是否有用户提供的良好格式-以“优雅”的方式


谢谢

一些常见的技术包括:

  • 将用户交互和程序逻辑(此处为温度转换)分为不同的类。单独对逻辑进行单元测试。通常不进行用户交互的单元测试,但是集成测试整个程序,包括用户交互(您可以使用JUnit或其他一些工具)
  • 不要每次读取输入时都创建新的
    扫描仪。始终使用相同的
    扫描仪。在这种情况下,注入一个不同的
    扫描器
    ,从
    系统之外的其他来源读取数据,就不会太困难了(如果你真的坚持要创建一个新的
    扫描仪
    ,你可能会有一种方法,在生产中创建一个从
    系统读取的
    扫描仪。在测试中创建一个从其他源读取的扫描仪;但正如我所说的,不用麻烦了)
  • 出于测试目的,您还可以将
    System.in
    设置为键盘以外的其他输入流。和/或类似地,将
    System.out
    重新布线到不同的输出流,以便测试写入其中的内容

    • 一些常用技术包括:

      • 将用户交互和程序逻辑(此处为温度转换)分离到单独的类中。单独对逻辑进行单元测试。通常情况下,不会对用户交互进行单元测试,但集成会测试整个程序,包括用户交互(您可以使用JUnit或其他工具进行测试)
      • 不要每次读取输入时都创建一个新的
        扫描仪
        。在整个过程中使用相同的
        扫描仪
        。在这种情况下,注入一个不同的
        扫描仪
        ,从
        系统中以外的其他源进行读取,以便进行测试(如果你真的坚持要创建一个新的
        扫描仪
        ,你可能会有一种方法,在生产中创建一个从
        系统读取的
        扫描仪。在测试中创建一个从其他源读取的扫描仪;但正如我所说的,不用麻烦了)
      • 出于测试目的,您还可以将
        System.in
        设置为键盘以外的其他输入流。和/或类似地,将
        System.out
        重新布线到不同的输出流,以便测试写入其中的内容
      我创建了一个库,它提供了填充
      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
          }
      }
      
      不幸的是,系统规则只支持JUnit 4。我正在为系统规则开发一个独立于测试框架的替代方案。

      我创建了一个库,该库提供填充
      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
          }
      }
      

      不幸的是,系统规则只支持JUnit 4。我正在为系统规则开发一个独立于测试框架的替代方案。

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

      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!
       ...
      }
      

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

      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!
       ...
      }