如何为扫描仪编写 junit 测试? (读取文件)

How to write a junit test for a scanner? (Reading a file)

我有一个扫描文件并为对象赋值的方法:

private List<Customer> customerList = new ArrayList<Customer>();

public void scanLocalFile() throws FileNotFoundException {
  File file = new File("input.txt");
  Scanner scan = new Scanner(file);
  while (scan.hasNextLine()) {
      String[] fields = line.split(";");
      String name = fields[0];
      String score = fields[1];

  Customer customer = new Customer(name, score);
  customerList.add(customer);
  }
scan.close();
}

如何为这样的方法编写 junit 测试?是否也可以使用相同的文件 ("input.txt") 进行单元测试?

文件结构:

John Smith;45;
Adam West;78;

使此代码可单元测试的基本方法是不对 input.txt 文件的使用进行硬编码。

File 作为参数传递给方法,以便您可以在测试期间 运行 任意文件的方法。

我会更进一步说:传入 ReaderScanner 有一个接受 Reader 的构造函数,这样您就不必在单元测试期间弄乱文件了。

例如,您可以使用作为“文件内容”的硬编码字符串构造一个StringReader

StringReader sr = new StringReader("John Smith;45;\nAdam West;78;");

但是请注意,如果您传入 Reader,则不应在末尾关闭 Scanner,因为那样会关闭 Reader;代码关闭未打开的 Reader(或 WriterInput/OutputStream;通常是任何资源)是不好的做法。

public void scanLocalFile(Reader r) {
  Scanner scan = new Scanner(r);
  while (scan.hasNextLine()) {
     // ...
  }
}

实际上,由于您只是从扫描仪读取行,我认为最好改用 BufferedReader:

public void scanLocalFile(Reader r) {
  new BufferedReader(r).lines()
      .map(line -> {
        String[] fields = line.split(";");
        return new Customer(fields[0], fields[1]);
      })
      .forEach(customerList::add);
}