1

我需要测试合同义务程序。
我没有看到任何直接的方法来测试这种方法。它违反了单一职责原则,并且干了太多事情。
我会知道,如何安全地将以下职责提取到新方法或类中:

public void askUserPathAndWord() {

        BufferedReader bufferedReader = new BufferedReader(
                new InputStreamReader(System.in));
        String path;
        String whatFind;
        BlockingQueue<File> queue = new LinkedBlockingQueue<File>();

        try {
            System.out.println("Please, enter a Path and Word"
                    + "(which you want to find):");
            System.out.println("Please enter a Path:");
            path = bufferedReader.readLine();
            System.out.println("Please enter a Word:");
            whatFind = bufferedReader.readLine();

            if (path != null && whatFind != null) {

                File endOfWorkFile = new File("GameOver.tmp");
                CountDownLatch latch = new CountDownLatch(2);

                FolderScan folderScan = new FolderScan(path, queue, latch,
                        endOfWorkFile);
                FileScan fileScan = new FileScan(whatFind, queue, latch,
                        endOfWorkFile);

                Executor executor = Executors.newCachedThreadPool();
                executor.execute(folderScan);
                executor.execute(fileScan);

                latch.await();
                System.out.println("Thank you!");
            } else {
                System.out.println("You did not enter anything");
            }

        } catch (IOException | RuntimeException e) {
            System.out.println("Wrong input!");
            e.printStackTrace();
        } catch (InterruptedException e) {
            System.out.println("Interrupted.");
            e.printStackTrace();
        }
    }

问题:
我们如何能够安全地执行后续步骤:

  • 向用户询问单词和路径;
  • 给定一个词,创建一个具有正确参数的 FileScan(工厂);
  • 给定一个路径,创建一个具有正确参数的 FolderScan(一个工厂);
  • 给定两个runnables和一个latch,创建一个ExecutorService,将它们排队,然后等待latch。
4

2 回答 2

3

As with most refactorings a safe first step is to test the method as it currently stands. Then refactor the code into logical groups that have the necessary responsibilities - throughout this process your previously written tests should not break. Then you can abandon your original test which tests too many things in favour of tests that solely make assertions about the new code that you have written

于 2013-02-27T13:09:29.783 回答
1

这就是我将重构该方法的方式,主要使用 IDE 的提取方法功能和常识。最好为该方法编写一个测试,以确保重构没有破坏任何东西。

class PathAndWord {
    final String path;
    final String whatFind;

    PathAndWord(String path, String whatFind) {
        this.path = path;
        this.whatFind = whatFind;
    }

    boolean isProperlyInitialized() {
        return path != null && whatFind != null;
    }
}

public void askUserPathAndWord() {
    try {
        tryToAskUserPathAndWord();
    } catch (IOException | RuntimeException e) {
        System.out.println("Wrong input!");
        e.printStackTrace();
    } catch (InterruptedException e) {
        System.out.println("Interrupted.");
        e.printStackTrace();
    }
}

private void tryToAskUserPathAndWord() throws IOException, InterruptedException {
    PathAndWord pathAndWord = readPathAndWord();

    if (pathAndWord.isProperlyInitialized()) {
        performScan(pathAndWord, "GameOver.tmp");
        System.out.println("Thank you!");
    } else {
        System.out.println("You did not enter anything");
    }
}

private PathAndWord readPathAndWord() throws IOException {
    System.out.println("Please, enter a Path and Word (which you want to find):");

    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));

    String path = readPath(bufferedReader);
    String whatFind = readWord(bufferedReader);
    return new PathAndWord(path, whatFind);
}

private String readPath(BufferedReader bufferedReader) throws IOException {
    System.out.println("Please enter a Path:");
    return bufferedReader.readLine();
}

private String readWord(BufferedReader bufferedReader) throws IOException {
    System.out.println("Please enter a Word:");
    return bufferedReader.readLine();
}

private void performScan(PathAndWord pathAndWord, String endOfWorkFileName) throws InterruptedException {
    BlockingQueue<File> queue = new LinkedBlockingQueue<File>();

    File endOfWorkFile = new File(endOfWorkFileName);
    CountDownLatch latch = new CountDownLatch(2);

    FolderScan folderScan = new FolderScan(pathAndWord.path, queue, latch,
            endOfWorkFile);
    FileScan fileScan = new FileScan(pathAndWord.whatFind, queue, latch,
            endOfWorkFile);

    Executor executor = Executors.newCachedThreadPool();
    executor.execute(folderScan);
    executor.execute(fileScan);

    latch.await();
}
于 2013-02-27T13:30:32.787 回答