为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

PIPIONE 2022-09-28 15:52:29
当尝试模拟控制台输入时,测试的行为不符合我的预期我为控制台输入、输出创建了一个包装类,并尝试模拟其行为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;}我的测试尝试@Testpublic void testReadPlayerNameShouldReturnNameString() {    String testName = "John Doe";    ConsoleReaderWriter testReaderWriter = mock(ConsoleReaderWriter.class);    when(testReaderWriter.readLine()).thenReturn("John Doe");    assertEquals(testName, underTest.readPlayerName());}我正在使用莫基托。当我运行测试时,它会提示我从控制台输入输入。测试通过,如果我输入预期的名称,但是,我想让它自动进行,这样我就不必在测试运行时输入任何输入。提前致谢。
查看完整描述

3 回答

?
慕沐林林

TA贡献2016条经验 获得超9个赞

请看一下这个例子:


@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());

   }

}


查看完整回答
反对 回复 2022-09-28
?
一只名叫tom的猫

TA贡献1906条经验 获得超2个赞

您需要将模拟对象注入到 underTest 实例中。


在 UnderTest 类本身中,请确保不要使用“新建”来创建控制台阅读器依赖项,而是从外部接受它,例如使用构造函数。


它可能是类似于以下内容的内容:


@Test

public 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());

}


查看完整回答
反对 回复 2022-09-28
?
BIG阳

TA贡献1859条经验 获得超6个赞

这里:

ConsoleReaderWriter testReaderWriter = mock(ConsoleReaderWriter.class);

问题是:该特定测试编写器应由您的受测对象使用。现在,您正在创建一个模拟对象,该对象与您打算验证的对象无关。因此,您可以遵循其他答案中给出的建议,并确保您的模拟实际传递给被测对象。

但更好的方法是:将生产代码与其正在使用的输入分离。您的问题从这里开始:

new InputStreamReader(System.in)

您正在基于固定输入创建读取器。别这样。

相反,例如,您可以将 InputStream 的实例传递给控制台阅读器对象。然后该流用于所有输入。然后,您不需要模拟任何内容,只需准备一个包含固定内容的流,然后将其提供给受测对象。

另一种方法是弄乱 System.in,例如这里概述的。


查看完整回答
反对 回复 2022-09-28
  • 3 回答
  • 0 关注
  • 60 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信