单元测试 WatchService

如何对这样的 watchservice 进行单元测试:


/**

 * Function to look for changes in a determinate directory

 * @param directory is the directory where to look for the changes

 * @return return a boolean that is true if have changes or false if not

 */


private static boolean watchDirectory(final String directory){


    boolean flag = false;


    Path path = Paths.get(directory);

    try {

        // get watch service which will monitor the directory

        WatchService watcher = path.getFileSystem().newWatchService();

        // associate watch service with the directory to listen to the event types

        path.register(watcher, StandardWatchEventKinds.ENTRY_CREATE);

        System.out.println("\nMonitoring directory for changes...");

        // listen to events

        WatchKey watchKey = watcher.take();

        // get list of events as they occur

        List<WatchEvent<?>> events = watchKey.pollEvents();


        for (WatchEvent event : events) {

            flag = false;

            //check if the events refers to a new file created

            if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) {

                flag = true;


                System.out.println("Created: " + event.context().toString() + " ;");

            }

        }

    } catch (IOException | InterruptedException e) {

        e.printStackTrace();

    }

    return flag;

}

它正在查找目录中的更改,如果创建了新文件,它返回一个值为 true 的标志,如果我没有找到更改,则返回该标志为 false。


慕斯王
浏览 139回答 2
2回答

饮歌长啸

使用 JUnit 规则TemporaryFolder,它允许创建临时文件夹和临时文件。测试只需要在被测试单元的生产代码中注入临时路径。@Rulepublic TemporaryFolder temporaryFolder = new TemporaryFolder();private File etcHost;@Beforepublic void set_file_with_content() throws Exception {&nbsp; &nbsp; etcHost = temporaryFolder.newFile();&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;}@Testpublic void on_etc_hosts_change_do_something() throws IOException {&nbsp; &nbsp; // given&nbsp; &nbsp; try(BufferedWriter bufferedWriter = Files.newBufferedWriter(etcHost.toPath(), UTF_8, WRITE)) {&nbsp; &nbsp; &nbsp; &nbsp; bufferedWriter.write("127.0.0.1 xxxxx.local");&nbsp; &nbsp; }&nbsp; &nbsp; // when&nbsp; &nbsp; try (BufferedWriter bufferedWriter = Files.newBufferedWriter(etcHost.toPath(), UTF_8, WRITE)) {&nbsp; &nbsp; &nbsp; &nbsp; bufferedWriter.write("127.1.1.1 zzzzz.local");&nbsp; &nbsp; &nbsp; &nbsp; bufferedWriter.newLine();&nbsp; &nbsp; &nbsp; &nbsp; bufferedWriter.write("127.0.0.1 xxxxx.local");&nbsp; &nbsp; }&nbsp; &nbsp; // then&nbsp; &nbsp; ...}这可能适用于简单的通知。但是您需要注意,WatchService这取决于依赖于操作系统和文件系统的底层实现。这意味着如果您在 Windows 上开发并且代码在 Linux 上运行,则此代码可能不会以完全相同的方式工作。如果您在 Linux 上开发并且生产也在 Linux 上运行,则更是如此,但是生产安装文件或文件夹的方式可能会妨碍正确观察路径的能力;这通常可能发生在容器中。上面的代码在我看来不正确,首先.take()不是在循环中,因此一旦轮询事件,该方法将退出。并且WatchKey在处理每个事件后不会重置。你可能想要这样的东西:try (WatchService watchService = FileSystems.getDefault().newWatchService()) {&nbsp; &nbsp; watchedParent.register(watchService, ENTRY_MODIFY, ENTRY_CREATE, OVERFLOW, ENTRY_DELETE);&nbsp; &nbsp; WatchKey wk;&nbsp; &nbsp; while ((wk = watchService.take()) != null) {&nbsp; &nbsp; &nbsp; &nbsp; for (WatchEvent<?> event : wk.pollEvents()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(event.kind() == OVERFLOW) { continue; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Path changedRelativePath = (Path) event.context();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (watchedFile.getFileName().equals(changedRelativePath)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; wk.reset();&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java