Java测试中Scanner获取输入抛出NoSuchElementException求助
问题原因
你在importarPetsDoAbrigo方法中两次创建new Scanner(System.in)实例,第一个Scanner读取完成后会自动关闭底层的System.in输入流。当第二个Scanner尝试读取时,输入流已处于关闭状态,因此抛出NoSuchElementException。
修复方案
1. 重构业务代码:复用同一个Scanner实例
不要重复创建Scanner,改用单个实例完成所有输入读取,避免多次关闭System.in:
public void importarPetsDoAbrigo() throws IOException, InterruptedException { Scanner scanner = new Scanner(System.in); // 仅创建一次Scanner System.out.println("Digite o id ou nome do abrigo:"); String idOuNome = scanner.nextLine(); System.out.println("Digite o nome do arquivo CSV:"); String nomeArquivo = scanner.nextLine(); BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(nomeArquivo)); } catch (IOException e) { System.out.println("Erro ao carregar o arquivo: " + nomeArquivo); scanner.close(); return; } String line; while ((line = reader.readLine()) != null) { String[] campos = line.split(","); String tipo = campos[0].toUpperCase(); String nome = campos[1]; String raca = campos[2]; int idade = Integer.parseInt(campos[3]); String cor = campos[4]; Float peso = Float.parseFloat(campos[5]); Pet pet = new Pet(raca, nome, tipo, cor, idade, peso); String uri = "http://localhost:8080/abrigos/" + idOuNome + "/pets"; HttpResponse<String> response = client.dispararRequisicaoPost(uri, pet); int statusCode = response.statusCode(); String responseBody = response.body(); if (statusCode == 200) { System.out.println("Pet cadastrado com sucesso: " + nome); } else if (statusCode == 404) { System.out.println("Id ou nome do abrigo não encontado!"); break; } else if (statusCode == 400 || statusCode == 500) { System.out.println("Erro ao cadastrar o pet: " + nome); System.out.println(responseBody); break; } } reader.close(); scanner.close(); }
2. 修复测试代码:修正Verify语法+恢复原始输入流
测试中需要修正verify的语法错误,同时在测试结束后恢复System.in的原始流,避免影响其他测试用例:
@Test public void deveVerificarSeImportouOsPetsDoAbrigo() throws IOException, InterruptedException { InputStream originalIn = System.in; // 保存原始输入流 try { String userInput = "Test" + System.lineSeparator() + "pets.csv"; ByteArrayInputStream bais = new ByteArrayInputStream(userInput.getBytes()); System.setIn(bais); when(client.dispararRequisicaoPost(anyString(), any(Pet.class))).thenReturn(response); petsService.importarPetsDoAbrigo(); verify(client, atLeast(1)).dispararRequisicaoPost(anyString(), any(Pet.class)); } finally { System.setIn(originalIn); // 恢复原始输入流 } }
额外注意事项
- 不要频繁创建Scanner读取
System.in:Scanner会关联底层输入流,关闭Scanner时会同步关闭System.in,导致后续无法读取输入。 - 测试中修改
System.in后必须恢复:否则会影响其他依赖标准输入的测试用例。 - 业务代码中若无需关闭标准输入流,也可以选择不关闭Scanner,但复用实例是核心要求。
内容的提问来源于stack exchange,提问作者Andrews
相关产品推荐
相关产品推荐

