2

我的任务是编写一个测试程序来评估学生的作业是否有效。学生们正在用 Java 编写一个石头、纸、剪刀游戏,并通过要求用户在命令行中输入来上交一个玩 n 轮游戏的单一班级。所有这些学生都将使用一个或多个 Scanner 对象从控制台读取输入,因此我需要让我的测试程序模拟一些预定的输入并检查预期的输出。我覆盖 System.in,因此当学生调用 时Scanner myReader = new Scanner(System.in);,我可以指示输入是什么(使用 ByteArrayInputStream)。要了解我是如何开始的:

public class TestRockPaperScissors extends RockPaperScissors{
public static void main(String[] args){
    InputStream stdin = System.in;
    try {
    System.setIn(new ByteArrayInputStream("<test inputs here>".getBytes()));
    RockPaperScissors.main(null); // This will be student code in another file.
    } finally {
        System.setIn(stdin);
    }

}

问题是,这只适用于学生只使用 System.in 创建单个扫描仪的情况。否则,我会收到错误,因为没有输入可供第二个 Scanner 使用 .next() 。

TL;DR... 鉴于我看不到 RockPaperScissors.main(null) 调用的来源,我如何为任意数量的扫描仪模拟控制台输入?

4

2 回答 2

1

Ask the students to write an object that runs RockPaperScissors by getting values from an InputStream, and writing results to a PrintStream, i.e. to write an implementation of the following interface

public interface RockPaperScissors {
    void runGame(InputStream in, PrintStream out) throws IOException;
}

That will allow them to test their own program using an instance of their class taking System.in and System.out as argument.

And that will allow you to unit test their program by passing your own ByteArrayInputStream containing the sequence of inputs, and your own ByteArrayOutputStream containing the output generated by the program, that you'll also be able to verify.

BTW, shouldn't the students learn to unit test their own code?

于 2013-02-17T08:52:45.480 回答
1

您可以使用系统规则库的StandardOutputStreamLogTextFromStandardInputStream规则为命令行界面编写更清晰的测试。

public class RockPaperScissorsTest() {
  @Rule
  public StandardOutputStreamLog log = new StandardOutputStreamLog();

  @Rule
  public TextFromStandardInputStream systemInMock = emptyStandardInputStream();

  @Test
  public void test1() {
    systemInMock.provideText("<test input>");
    RockPaperScissors.main(null);
    assertTrue(log.getLog().contains("<expected output>"));
  }

  @Test
  public void test2() {
    systemInMock.provideText("<another test input>");
    RockPaperScissors.main(null);
    assertTrue(log.getLog().contains("<expected output>"));
  }
}
于 2013-02-17T16:40:26.900 回答