当尝试模拟控制台输入时,测试的行为不符合我的预期
我为控制台输入,输出创建了包装器类,并尝试模拟其行为
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());
}
我正在使用Mockito。当我运行测试时,它提示我从控制台输入输入。如果我输入了预期的名称,则测试通过了,但是,我想使其自动进行,因此在测试运行时我不必输入任何输入。预先感谢。
答案 0 :(得分: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());
}
}
答案 1 :(得分:1)
这里:
ConsoleReaderWriter testReaderWriter = mock(ConsoleReaderWriter.class);
情况是:特定的testReaderWriter应该由受测对象 使用。现在,您正在创建一个模拟对象,该对象与要验证的对象没有任何关系。因此,您可以按照其他答案中的建议进行操作,并确保将 mock 实际传递给被测对象。
但是更好的方法是:将生产代码与其使用的输入分离。您的问题从这里开始:
new InputStreamReader(System.in)
您正在创建基于固定输入的阅读器。不要那样做
例如,您可以将InputStream的实例传递到ConsoleReaderWriter对象。然后将该流用于所有输入。然后,您无需进行任何模拟,只需准备具有固定内容的流,然后将其提供给被测对象即可。
另一种方法是弄乱System.in,例如概述为here。
答案 2 :(得分:1)
您需要将模拟对象注入underTest实例。
在UnderTest类本身中,请确保您不使用“ new”来创建ConsoleReaderWriter依赖项,而是从外部(例如,使用构造函数)接受它。
可能与以下内容类似:
@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());
}