Junit方法测试,用户整数输入
Junit method testing, user integer input
我不知道如何在单元测试中为 integers/floats/doubles 模拟用户输入。我用它来模拟字符串输入:
@Test
public void testSetName() {
String expectedResult = "Jason";
InputStream in = new ByteArrayInputStream(expectedResult.getBytes());
System.setIn(in);
assertEquals(expectedResult, MainClass.setName());
}
但我不知道如何输入整数。
这是我正在测试的方法:
public static int setAge() {
Scanner input = new Scanner(System.in);
int age = 0;
boolean done = false;
while (!done) {
System.out.print("Age: ");
try {
age = input.nextInt();
done = true;
} catch (InputMismatchException e) {
System.out.println("Please enter a valid age!");
input.nextLine();
}
}
return age;
}
所以我想通了。它可以以与字符串完全相同的方式完成,因为这只是发送一个输入而不是特定类型。就我而言,我要测试的方法是:
public static int setAge() {
Scanner input = new Scanner(System.in);
int age = 0;
boolean done = false;
while (!done) {
System.out.print("Age: ");
try {
age = input.nextInt();
done = true;
} catch (InputMismatchException e) {
System.out.println("Please enter a valid age!");
input.nextLine();
}
}
return age;
}
我写的测试是这样的:
@Test
public void testSetAge() {
String expectedResult = "5";
InputStream in = new ByteArrayInputStream(expectedResult.getBytes());
System.setIn(in);
assertEquals(5, MainClass.setAge());
}
我不确定这是否是 best/proper 完成此操作的方法,但我就是这样做的。
我会用一个随机的测试例子来解释逻辑。您应该为系统 input/output 函数创建一个包装器。你可以使用依赖注入来做到这一点,给我们一个可以请求新整数的 class:
public static class IntegerAsker {
private final Scanner scanner;
private final PrintStream out;
public IntegerAsker(InputStream in, PrintStream out) {
scanner = new Scanner(in);
this.out = out;
}
public int ask(String message) {
out.println(message);
return scanner.nextInt();
}
}
然后您可以使用模拟框架为您的函数创建测试(在此示例中,我使用的是 Mockito):
@Test
public void getsIntegerWhenWithinBoundsOfOneToTen() throws Exception {
IntegerAsker asker = mock(IntegerAsker.class);
when(asker.ask(anyString())).thenReturn(3);
assertEquals(getBoundIntegerFromUser(asker), 3);
}
@Test
public void asksForNewIntegerWhenOutsideBoundsOfOneToTen() throws Exception {
IntegerAsker asker = mock(IntegerAsker.class);
when(asker.ask("Give a number between 1 and 10")).thenReturn(99);
when(asker.ask("Wrong number, try again.")).thenReturn(3);
getBoundIntegerFromUser(asker);
verify(asker).ask("Wrong number, try again.");
}
然后编写通过测试的函数。该函数更加简洁,因为您可以删除 asking/getting 整数重复,并且封装了实际的系统调用。
public static void main(String[] args) {
getBoundIntegerFromUser(new IntegerAsker(System.in, System.out));
}
public static int getBoundIntegerFromUser(IntegerAsker asker) {
int input = asker.ask("Give a number between 1 and 10");
while (input < 1 || input > 10)
input = asker.ask("Wrong number, try again.");
return input;
}
我不知道如何在单元测试中为 integers/floats/doubles 模拟用户输入。我用它来模拟字符串输入:
@Test
public void testSetName() {
String expectedResult = "Jason";
InputStream in = new ByteArrayInputStream(expectedResult.getBytes());
System.setIn(in);
assertEquals(expectedResult, MainClass.setName());
}
但我不知道如何输入整数。 这是我正在测试的方法:
public static int setAge() {
Scanner input = new Scanner(System.in);
int age = 0;
boolean done = false;
while (!done) {
System.out.print("Age: ");
try {
age = input.nextInt();
done = true;
} catch (InputMismatchException e) {
System.out.println("Please enter a valid age!");
input.nextLine();
}
}
return age;
}
所以我想通了。它可以以与字符串完全相同的方式完成,因为这只是发送一个输入而不是特定类型。就我而言,我要测试的方法是:
public static int setAge() {
Scanner input = new Scanner(System.in);
int age = 0;
boolean done = false;
while (!done) {
System.out.print("Age: ");
try {
age = input.nextInt();
done = true;
} catch (InputMismatchException e) {
System.out.println("Please enter a valid age!");
input.nextLine();
}
}
return age;
}
我写的测试是这样的:
@Test
public void testSetAge() {
String expectedResult = "5";
InputStream in = new ByteArrayInputStream(expectedResult.getBytes());
System.setIn(in);
assertEquals(5, MainClass.setAge());
}
我不确定这是否是 best/proper 完成此操作的方法,但我就是这样做的。
我会用一个随机的测试例子来解释逻辑。您应该为系统 input/output 函数创建一个包装器。你可以使用依赖注入来做到这一点,给我们一个可以请求新整数的 class:
public static class IntegerAsker {
private final Scanner scanner;
private final PrintStream out;
public IntegerAsker(InputStream in, PrintStream out) {
scanner = new Scanner(in);
this.out = out;
}
public int ask(String message) {
out.println(message);
return scanner.nextInt();
}
}
然后您可以使用模拟框架为您的函数创建测试(在此示例中,我使用的是 Mockito):
@Test
public void getsIntegerWhenWithinBoundsOfOneToTen() throws Exception {
IntegerAsker asker = mock(IntegerAsker.class);
when(asker.ask(anyString())).thenReturn(3);
assertEquals(getBoundIntegerFromUser(asker), 3);
}
@Test
public void asksForNewIntegerWhenOutsideBoundsOfOneToTen() throws Exception {
IntegerAsker asker = mock(IntegerAsker.class);
when(asker.ask("Give a number between 1 and 10")).thenReturn(99);
when(asker.ask("Wrong number, try again.")).thenReturn(3);
getBoundIntegerFromUser(asker);
verify(asker).ask("Wrong number, try again.");
}
然后编写通过测试的函数。该函数更加简洁,因为您可以删除 asking/getting 整数重复,并且封装了实际的系统调用。
public static void main(String[] args) {
getBoundIntegerFromUser(new IntegerAsker(System.in, System.out));
}
public static int getBoundIntegerFromUser(IntegerAsker asker) {
int input = asker.ask("Give a number between 1 and 10");
while (input < 1 || input > 10)
input = asker.ask("Wrong number, try again.");
return input;
}