为了账号安全,请及时绑定邮箱和手机立即绑定

单元测试 WatchService

单元测试 WatchService

慕斯王 2021-10-20 16:14:44
如何对这样的 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。
查看完整描述

2 回答

?
饮歌长啸

TA贡献1951条经验 获得超3个赞

使用 JUnit 规则TemporaryFolder,它允许创建临时文件夹和临时文件。测试只需要在被测试单元的生产代码中注入临时路径。


@Rule

public TemporaryFolder temporaryFolder = new TemporaryFolder();

private File etcHost;


@Before

public void set_file_with_content() throws Exception {

    etcHost = temporaryFolder.newFile();        

}


@Test

public void on_etc_hosts_change_do_something() throws IOException {

    // given

    try(BufferedWriter bufferedWriter = Files.newBufferedWriter(etcHost.toPath(), UTF_8, WRITE)) {

        bufferedWriter.write("127.0.0.1 xxxxx.local");

    }


    // when

    try (BufferedWriter bufferedWriter = Files.newBufferedWriter(etcHost.toPath(), UTF_8, WRITE)) {

        bufferedWriter.write("127.1.1.1 zzzzz.local");

        bufferedWriter.newLine();

        bufferedWriter.write("127.0.0.1 xxxxx.local");

    }


    // then

    ...

}

这可能适用于简单的通知。但是您需要注意,WatchService这取决于依赖于操作系统和文件系统的底层实现。这意味着如果您在 Windows 上开发并且代码在 Linux 上运行,则此代码可能不会以完全相同的方式工作。如果您在 Linux 上开发并且生产也在 Linux 上运行,则更是如此,但是生产安装文件或文件夹的方式可能会妨碍正确观察路径的能力;这通常可能发生在容器中。


上面的代码在我看来不正确,首先.take()不是在循环中,因此一旦轮询事件,该方法将退出。并且WatchKey在处理每个事件后不会重置。你可能想要这样的东西:


try (WatchService watchService = FileSystems.getDefault().newWatchService()) {

    watchedParent.register(watchService, ENTRY_MODIFY, ENTRY_CREATE, OVERFLOW, ENTRY_DELETE);


    WatchKey wk;

    while ((wk = watchService.take()) != null) {

        for (WatchEvent<?> event : wk.pollEvents()) {

            if(event.kind() == OVERFLOW) { continue; }


            Path changedRelativePath = (Path) event.context();

            if (watchedFile.getFileName().equals(changedRelativePath)) {

                ...

            }

        }

        wk.reset();

    }

}


查看完整回答
反对 回复 2021-10-20
  • 2 回答
  • 0 关注
  • 138 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信