使用Scanner对用户输入进行junit测试

Ros*_*oss 9 java junit mocking mockito

我必须在类中测试一个方法,该方法使用Scanner类进行输入.

package com.math.calculator;

import java.util.Scanner;

public class InputOutput {

    public String getInput() {
        Scanner sc = new Scanner(System.in);
        return sc.nextLine();
    }
}
Run Code Online (Sandbox Code Playgroud)

我想使用JUnit测试它,但不知道如何做到这一点.

我尝试使用以下代码,但它不会工作.

package com.math.calculator;

import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class InputOutputTest {

    @Test
    public void shouldTakeUserInput() {
        InputOutput inputOutput= new InputOutput();

        assertEquals("add 5", inputOutput.getInput());
    }
}
Run Code Online (Sandbox Code Playgroud)

我也想和Mockito一起尝试(使用模拟......当...然后返回)但不知道该怎么做.

Cod*_*der 17

您可以System.in使用System.setIn()方法更改流.

试试这个,

@Test
public void shouldTakeUserInput() {
    InputOutput inputOutput= new InputOutput();

    String input = "add 5";
    InputStream in = new ByteArrayInputStream(input.getBytes());
    System.setIn(in);

    assertEquals("add 5", inputOutput.getInput());
}
Run Code Online (Sandbox Code Playgroud)

您刚刚修改了该System.in字段.System.in基本上是InputStreamconsole(从而在控制台中输入)读取.但是你只是修改了它,让系统从提供的中读取inputstream.所以它不再从控制台读取,而是从提供的输入流中读取.

  • 有效 :)。你能告诉我这是如何工作的吗? (2认同)

Ste*_*ner 5

您可以使用系统规则库的TextFromStandardInputStream规则为命令行界面编写清晰的测试。

public void MyTest {
  @Rule
  public final TextFromStandardInputStream systemInMock
    = emptyStandardInputStream();

  @Test
  public void shouldTakeUserInput() {
    systemInMock.provideLines("add 5", "another line");
    InputOutput inputOutput = new InputOutput();
    assertEquals("add 5", inputOutput.getInput());
  }
}
Run Code Online (Sandbox Code Playgroud)

  • @Stefan 您的解决方案效果很好,添加此依赖项,一切顺利!`<dependency>` ` <groupId>com.github.stefanbirkner</groupId>` `<artifactId>系统规则</artifactId>` `<version>1.16.0</version>` `</dependency>` (2认同)