Mock BufferedReader.readline()桩方法失效,测试卡住求助
问题描述
我的项目需要用户在控制台输入命令行,使用BufferedReader.readLine()捕获用户输入,该BufferedReader处于while循环中,会持续读取新命令并处理。View类中,BufferedReader会在输入非"Q"时持续读取行。
测试时我尝试用Mock对象桩化readLine()方法使其返回指定命令,代码如下:
@Test void whenCommandIsR_CallBuildRectangle() throws IOException { View view = new View(); BufferedReader bufferedReader = mock(BufferedReader.class); when(bufferedReader.readLine()).thenReturn("C 10 10").thenReturn("Q"); view.inputCommand(); verify(bufferedReader, times(2)).readLine(); }
但运行测试时,控制台卡在BufferedReader.readLine()处等待输入,桩化并未生效。请问有办法强制BufferedReader.readLine()返回指定值吗?
解决方案
问题核心是Mock对象没有被注入到View类中,View内部仍在使用关联控制台输入的原始BufferedReader实例,而非你创建的Mock对象。
解决步骤如下:
重构View类,提供依赖注入入口
给View类添加构造方法或setter方法,允许外部传入BufferedReader,替代内部直接创建控制台关联实例的逻辑:public class View { private BufferedReader reader; // 构造方法注入 public View(BufferedReader reader) { this.reader = reader; } // 可选:提供setter方法用于动态替换 public void setReader(BufferedReader reader) { this.reader = reader; } public void inputCommand() throws IOException { String command; while (!(command = reader.readLine()).equals("Q")) { // 命令处理逻辑 } } }在测试中传入Mock对象
修改测试代码,将Mock的BufferedReader通过构造方法或setter传入View:@Test void whenCommandIsR_CallBuildRectangle() throws IOException { BufferedReader mockReader = mock(BufferedReader.class); when(mockReader.readLine()).thenReturn("C 10 10").thenReturn("Q"); // 通过构造方法传入Mock实例 View view = new View(mockReader); view.inputCommand(); verify(mockReader, times(2)).readLine(); }
修改后,View会使用你桩化的Mock对象,readLine()将返回指定值,测试不会再卡在等待控制台输入的状态。
内容的提问来源于stack exchange,提问作者Winwin
相关产品推荐
相关产品推荐

