首页 > 解决方案 > Scanner.nextLine() 忽略空格?(爪哇)

问题描述

我有一个命令行游戏并且正在使用 JUnit 进行测试,这是测试:

@Test
  public void testBattle() throws IOException{
    String input = "go forward\ngo left\ntake Pointy Stick\ngo backward\ngo " +
            "right\nnormal attack\nnormal attack\nquit\n";
    provideInput(input);
    actual = new File("src/main/testFiles/testBattle.txt");
    expected = new File("src/main/testFiles/testBattleExpected.txt");
    PrintStream o = new PrintStream(actual);
    System.setOut(o);

    ui.gameLoop();
    assertTrue(FileUtils.contentEqualsIgnoreEOL(actual, expected, null));

  }

这是提供输入法:

 private void provideInput(String data) {
    String newdata = data.trim();
    testIn = new ByteArrayInputStream(newdata.getBytes());
    System.setIn(testIn);
  }

我正在扫描下一行,所以:

command = input.nextLine().toLowerCase().trim();

这里的“输入”代表扫描仪对象,但我仍然收到此错误,特别是当第一次“正常攻击”传递到 System.in 时

java.util.NoSuchElementException: No line found

在上面那条线上。我以为下一行忽略了空格?如果不是,我的字符串格式错误以不包含它吗?

编辑:从 UI.gameLoop() 的前几行我只初始化扫描仪一次。

public void gameLoop() throws IOException, JsonSyntaxException {
    input = new Scanner(System.in);
    engine = new GameEngine(path);

标签: javajunitcommand-line-interfacejava.util.scanner

解决方案


我以为下一行忽略了空格?

没有。根据javadocs,它读取下一个行尾序列(或到 EOF),然后返回所有内容,但不包括行尾序列。

如果你得到

java.util.NoSuchElementException: No line found

这意味着Scanner已经到达输入流的末尾,或者(可能)正在Scanner尝试从代码中其他地方过早关闭的输入流中读取。

我们可以猜测真正的问题是什么,但是如果没有看到 >>your<< minimum reproducible example,我们就无法更进一步。


其实,我只是发现了一个线索:

...我正在使用 JUnit 进行测试...

这可能是您问题的根源。JVM 在其生命周期中只能“读到底System.in”一次。如果你有两个或更多的 JUnit 测试需要这样做,这将是很困难的,除非你能找到一种方法来“模拟”System.in变量。

重新组织代码可能会更简单,这样您就可以从某个流中获取作为参数传递给游戏代码的输入。通过重组,您可以更轻松地编写单元测试。


推荐阅读