Java JUnit测试-如何检查扫描仪的各种输入不匹配
我正在尝试为一个程序编写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);
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!
...
}