如何通过模拟自动针对控制台输入进行测试?

当尝试模拟控制台输入时,测试的行为不符合我的预期


我为控制台输入、输出创建了一个包装类,并尝试模拟其行为


public class ConsoleReaderWriter {


public void printLine(String message) {


    System.out.println(message);

}


public String readLine() {

    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));

    String result = "";

    try {

        result = bufferedReader.readLine();

    } catch (IOException e) {

        System.err.print(e);

    }

    return result;


}

}


要测试的方法


public String readPlayerName() {

    consoleReaderWriter.printLine("> What is your name?");

    String playerName = consoleReaderWriter.readLine();

    return playerName;

}

我的测试尝试


@Test

public void testReadPlayerNameShouldReturnNameString() {

    String testName = "John Doe";


    ConsoleReaderWriter testReaderWriter = mock(ConsoleReaderWriter.class);


    when(testReaderWriter.readLine()).thenReturn("John Doe");


    assertEquals(testName, underTest.readPlayerName());

}

我正在使用莫基托。当我运行测试时,它会提示我从控制台输入输入。测试通过,如果我输入预期的名称,但是,我想让它自动进行,这样我就不必在测试运行时输入任何输入。提前致谢。


PIPIONE
浏览 79回答 3
3回答

慕沐林林

请看一下这个例子:@RunWith(MockitoJUnitRunner.class)public class TestClass {   @Mock   ConsoleReaderWriter crw;   @InjectMocks   UnderTestClass underTest;   //Some other fields   @Test   public void testReadPlayerNameShouldReturnNameString() {      String testName = "John Doe";      when(crw.readLine()).thenReturn("John Doe");      assertEquals(testName, underTest.readPlayerName());   }}

一只名叫tom的猫

您需要将模拟对象注入到 underTest 实例中。在 UnderTest 类本身中,请确保不要使用“新建”来创建控制台阅读器依赖项,而是从外部接受它,例如使用构造函数。它可能是类似于以下内容的内容:@Testpublic void testReadPlayerNameShouldReturnNameString() {    String testName = "John Doe";    ConsoleReaderWriter testReaderWriter = mock(ConsoleReaderWriter.class);    when(testReaderWriter.readLine()).thenReturn("John Doe");    UnderTest underTest = new UnderTest(testReaderWriter);                assertEquals(testName, underTest.readPlayerName());}

BIG阳

这里:ConsoleReaderWriter testReaderWriter = mock(ConsoleReaderWriter.class);问题是:该特定测试编写器应由您的受测对象使用。现在,您正在创建一个模拟对象,该对象与您打算验证的对象无关。因此,您可以遵循其他答案中给出的建议,并确保您的模拟实际传递给被测对象。但更好的方法是:将生产代码与其正在使用的输入分离。您的问题从这里开始:new InputStreamReader(System.in)您正在基于固定输入创建读取器。别这样。相反,例如,您可以将 InputStream 的实例传递给控制台阅读器对象。然后该流用于所有输入。然后,您不需要模拟任何内容,只需准备一个包含固定内容的流,然后将其提供给受测对象。另一种方法是弄乱 System.in,例如这里概述的。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java