Используйте правило 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();
}
}