如何测试含BufferedReader的控制台输入方法并修正测试阻塞问题
修正获取Double输入方法的单元测试
你的测试代码存在两个核心问题:一是没有实际调用CalcService的firstNumber方法,等于没测目标业务逻辑;二是直接依赖System.in,单元测试环境不支持交互式输入,导致进程阻塞。
解决方案:模拟System.in输入流
通过替换System.in的输入源,预先提供测试用的输入内容,避免阻塞。同时要在测试前后恢复原输入流,防止影响其他测试用例。
修正后的测试代码示例(基于JUnit 5):
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.io.ByteArrayInputStream; import java.io.InputStream; import static org.junit.jupiter.api.Assertions.assertEquals; public class CalcServiceTest { private CalcService calcService; private InputStream originalSystemIn; @BeforeEach void setUp() { calcService = new CalcService(); // 保存原System.in,测试后恢复 originalSystemIn = System.in; } @AfterEach void tearDown() { // 恢复原输入流 System.setIn(originalSystemIn); } @Test void firstNumberTest() { // 模拟输入:比如输入"3.14" String testInput = "3.14"; ByteArrayInputStream inputStream = new ByteArrayInputStream(testInput.getBytes()); System.setIn(inputStream); // 调用目标业务方法 calcService.firstNumber(); // 验证结果是否符合预期 assertEquals(3.14, calcService.inputA); } @Test void firstNumberWithNegativeInputTest() { // 测试负数输入场景 String testInput = "-5.6"; ByteArrayInputStream inputStream = new ByteArrayInputStream(testInput.getBytes()); System.setIn(inputStream); calcService.firstNumber(); assertEquals(-5.6, calcService.inputA); } }
补充说明
@BeforeEach和@AfterEach:分别在测试前后初始化CalcService、保存并恢复原System.in,保证每个测试用例的独立性。ByteArrayInputStream:将预设的字符串转为输入流,替换System.in,让firstNumber方法读取预设值而非等待控制台输入。- 封装优化建议:原业务代码中
inputA是类成员变量,若要遵循封装原则,建议添加public double getInputA()方法来获取值,避免直接访问成员变量。
内容的提问来源于stack exchange,提问作者Constantine S
相关产品推荐
相关产品推荐

